mirror of
https://github.com/j93es/browser-use-oauth.git
synced 2026-06-04 01:21:52 +09:00
코드 정리 및 개선: 파일 생성 로직 및 Playwright 설치 과정에서의 예외 처리 개선, 사용자 데이터 디렉토리 복사 시 로그 추가
This commit is contained in:
parent
d6803ad20e
commit
ba1e81177b
3 changed files with 179 additions and 46 deletions
136
setup.py
136
setup.py
|
|
@ -6,21 +6,27 @@ from browser_use import BrowserProfile, Agent
|
|||
from browser_use.llm import ChatGoogle
|
||||
from dotenv import load_dotenv
|
||||
import threading
|
||||
|
||||
load_dotenv(verbose=True, override=True)
|
||||
|
||||
os.makedirs(os.path.dirname("./data"), exist_ok=True)
|
||||
|
||||
|
||||
def create_file_from_example(target: str, example: str) -> bool:
|
||||
if not os.path.exists(target):
|
||||
if os.path.exists(example):
|
||||
with open(example, 'r', encoding='utf-8') as example_file, \
|
||||
open(target, 'w', encoding='utf-8') as target_file:
|
||||
with (
|
||||
open(example, "r", encoding="utf-8") as example_file,
|
||||
open(target, "w", encoding="utf-8") as target_file,
|
||||
):
|
||||
target_file.write(example_file.read())
|
||||
#os.startfile(target)
|
||||
# os.startfile(target)
|
||||
print(f"✅ {target} 파일이 {example}에서 생성되었습니다.")
|
||||
return True
|
||||
else:
|
||||
print(f"⚠️ {example} 파일이 존재하지 않습니다. {target} 생성에 실패했습니다.")
|
||||
print(
|
||||
f"⚠️ {example} 파일이 존재하지 않습니다. {target} 생성에 실패했습니다."
|
||||
)
|
||||
else:
|
||||
print(f"ℹ️ {target} 파일이 이미 존재합니다.")
|
||||
return False
|
||||
|
|
@ -30,7 +36,7 @@ def install_playwright_chrome():
|
|||
print("\n🛠️ Playwright의 Chromium을 설치 중입니다...")
|
||||
print("👉 이 작업은 시간이 걸릴 수 있습니다. 잠시 기다려주세요.")
|
||||
try:
|
||||
subprocess.run(['uv', 'run', 'playwright', 'install', 'chromium'], check=True)
|
||||
subprocess.run(["uv", "run", "playwright", "install", "chromium"], check=True)
|
||||
print("✅ Playwright Chrome 설치 완료.")
|
||||
except subprocess.CalledProcessError as e:
|
||||
if "already" in e.stdout.decode():
|
||||
|
|
@ -42,23 +48,28 @@ def install_playwright_chrome():
|
|||
|
||||
def prompt_yes_no(message: str) -> bool:
|
||||
print(message, end="")
|
||||
return input().strip().lower() in ['y', 'yes']
|
||||
return input().strip().lower() in ["y", "yes"]
|
||||
|
||||
|
||||
def i_dont_like_windows():
|
||||
# Windows인지 확인
|
||||
if os.name != 'nt':
|
||||
if os.name != "nt":
|
||||
return
|
||||
else:
|
||||
# run (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage").ACP
|
||||
try:
|
||||
result = subprocess.run(
|
||||
['powershell', '-Command', '(Get-ItemProperty "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage").ACP'],
|
||||
[
|
||||
"powershell",
|
||||
"-Command",
|
||||
'(Get-ItemProperty "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage").ACP',
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
check=True,
|
||||
)
|
||||
acp = result.stdout.strip()
|
||||
if acp == '65001':
|
||||
if acp == "65001":
|
||||
print("현재 Active Code Page가 UTF-8로 설정되어 있습니다.")
|
||||
return
|
||||
else:
|
||||
|
|
@ -68,12 +79,14 @@ def i_dont_like_windows():
|
|||
print("=======================================================")
|
||||
print("\n⚠️ Windows에서는 인코딩 문제가 발생합니다.")
|
||||
print("👉 엔터를 누르면 자동으로 intl.cpl이 열립니다.")
|
||||
print("👉 자세한 내용은 README.md에서 \"윈도우 인코딩 해결\"을 참조해주세요.\n")
|
||||
print("⚠️ 경고 : 이 작업은 윈도우에서 킹갓 대한민국의 프로그램들의 한글이 정상적으로 표시되지 않을 수 있습니다.")
|
||||
print('👉 자세한 내용은 README.md에서 "윈도우 인코딩 해결"을 참조해주세요.\n')
|
||||
print(
|
||||
"⚠️ 경고 : 이 작업은 윈도우에서 킹갓 대한민국의 프로그램들의 한글이 정상적으로 표시되지 않을 수 있습니다."
|
||||
)
|
||||
# Pause
|
||||
input("계속하려면 Enter 키를 누르세요...")
|
||||
|
||||
webbrowser.open('intl.cpl')
|
||||
webbrowser.open("intl.cpl")
|
||||
|
||||
print("👉 intl.cpl가 열렸습니다.\n")
|
||||
print("👉 관리자 옵션 -> 시스템 로켈 변경")
|
||||
|
|
@ -90,15 +103,17 @@ async def setup_user_data():
|
|||
print("✅ 이 작업은 Google API Key를 설정하고 나서 진행해야만합니다.")
|
||||
if prompt_yes_no("\033[1m\033[33m선택하시려면 y를 입력하세요 (y/n):\033[0m "):
|
||||
if os.getenv("GOOGLE_API_KEY") is None:
|
||||
print("⚠️ Google API Key가 설정되어 있지 않습니다. 먼저 Google API Key를 설정해주세요.")
|
||||
print(
|
||||
"⚠️ Google API Key가 설정되어 있지 않습니다. 먼저 Google API Key를 설정해주세요."
|
||||
)
|
||||
return
|
||||
print("======================================================")
|
||||
llm = ChatGoogle(
|
||||
model="gemini-2.0-flash",
|
||||
)
|
||||
initial_actions = [
|
||||
{'go_to_url': {'url': 'https://www.google.com', 'new_tab': False}},
|
||||
{'wait': {'seconds': 2147483647}},
|
||||
{"go_to_url": {"url": "https://www.google.com", "new_tab": False}},
|
||||
{"wait": {"seconds": 2147483647}},
|
||||
]
|
||||
|
||||
agent = Agent(
|
||||
|
|
@ -108,18 +123,74 @@ async def setup_user_data():
|
|||
initial_actions=initial_actions,
|
||||
browser_profile=BrowserProfile(
|
||||
disable_security=True,
|
||||
#stealth=True,
|
||||
# stealth=True,
|
||||
headless=False,
|
||||
device_scale_factor=1,
|
||||
window_size={"width": 1600, "height": 900},
|
||||
viewport={"width": 1600, "height": 900},
|
||||
user_data_dir="./data/user_data",
|
||||
ignore_default_args=['--enable-automation'],
|
||||
)
|
||||
args=[
|
||||
# "--disable-features=Translate,PasswordManagerDefaultEnabled",
|
||||
],
|
||||
ignore_default_args=[
|
||||
"--disable-datasaver-prompt",
|
||||
"--disable-component-extensions-with-background-pages",
|
||||
"--disable-prompt-on-repost",
|
||||
"--safeBrowse-disable-auto-update",
|
||||
"--install-autogenerated-theme=0,0,0",
|
||||
"--disable-speech-synthesis-api",
|
||||
"--ash-no-nudges",
|
||||
"--test-type=gpu",
|
||||
"--noerrdialogs",
|
||||
"--disable-external-intent-requests",
|
||||
"--disable-breakpad",
|
||||
"--disable-backgrounding-occluded-windows",
|
||||
"--export-tagged-pdf",
|
||||
"--disable-focus-on-load",
|
||||
"--suppress-message-center-popups",
|
||||
"--disable-renderer-backgrounding",
|
||||
"--hide-crash-restore-bubble",
|
||||
"--disable-back-forward-cache",
|
||||
"--allow-legacy-extension-manifests",
|
||||
# "--disable-field-trial-config", # 왜 이걸 끄면 웹사이트가 압축된 형태로 보이는 진 모르곘음
|
||||
"--disable-popup-blocking",
|
||||
"--disable-background-networking",
|
||||
"--no-first-run",
|
||||
"--disable-blink-features=AutomationControlled",
|
||||
"--password-store=basic",
|
||||
"--enable-network-information-downlink-max",
|
||||
"--allow-pre-commit-input",
|
||||
"--enable-features=NetworkService,NetworkServiceInProcess",
|
||||
"--metrics-recording-only",
|
||||
"--silent-debugger-extension-api",
|
||||
"--disable-features=AcceptCHFrame,AutoExpandDetailsElement,AvoidUnnecessaryBeforeUnloadCheckSync,CertificateTransparencyComponentUpdater,DestroyProfileOnBrowserClose,DialMediaRouteProvider,ExtensionManifestV2Disabled,GlobalMediaControls,HttpsUpgrades,ImprovedCookieControls,LazyFrameLoading,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate,AutomationControlled,BackForwardCache,OptimizationHints,ProcessPerSiteUpToMainFrameThreshold,InterestFeedContentSuggestions,CalculateNativeWinOcclusion,HeavyAdPrivacyMitigations,PrivacySandboxSettings4,AutofillServerCommunication,CrashReporting,OverscrollHistoryNavigation,InfiniteSessionRestore,ExtensionDisableUnsupportedDeveloper",
|
||||
"--disable-ipc-flooding-protection",
|
||||
"--disable-hang-monitor",
|
||||
"--disable-dev-shm-usage",
|
||||
"--disable-client-side-phishing-detection",
|
||||
"--log-level=2",
|
||||
"--generate-pdf-document-outline",
|
||||
"--disable-speech-api",
|
||||
"--disable-search-engine-choice-screen",
|
||||
"--no-service-autorun",
|
||||
"--no-pings",
|
||||
"--disable-component-update",
|
||||
'--simulate-outdated-no-au="Tue, 31 Dec 2099 23:59:59 GMT"',
|
||||
"--disable-background-timer-throttling",
|
||||
"--use-mock-keychain",
|
||||
"--disable-features=IsolateOrigins,site-per-process",
|
||||
# 아래는 기존 예시에 있던 인자들입니다. 필요에 따라 유지하거나 제거하세요.
|
||||
"--enable-automation",
|
||||
"--disable-extensions",
|
||||
"--hide-scrollbars",
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
print("======================================================\n")
|
||||
print("👉 브라우저가 열립니다. 필요한 로그인을 완료한 후 엔터키를 눌러 다음 단계로 진행하세요.")
|
||||
print(
|
||||
"👉 브라우저가 열립니다. 필요한 로그인을 완료한 후 엔터키를 눌러 다음 단계로 진행하세요."
|
||||
)
|
||||
input("계속하려면 Enter 키를 누르세요...\n")
|
||||
print("======================================================")
|
||||
|
||||
|
|
@ -134,7 +205,8 @@ async def setup_user_data():
|
|||
# 사용자가 'n'을 입력할 때까지 대기
|
||||
while True:
|
||||
user_input = input("").strip().lower()
|
||||
if user_input == '':
|
||||
if user_input == "":
|
||||
agent.stop()
|
||||
break
|
||||
|
||||
print("======================================================")
|
||||
|
|
@ -142,36 +214,44 @@ async def setup_user_data():
|
|||
else:
|
||||
print("🚫 설정이 취소되었습니다.")
|
||||
print("======================================================")
|
||||
print("⚠️ 이후에 USER_DATA_DIR을 설정하려면, .env 파일을 참고하여 USER_DATA_DIR을 설정하세요.\n")
|
||||
print(
|
||||
"⚠️ 이후에 USER_DATA_DIR을 설정하려면, .env 파일을 참고하여 USER_DATA_DIR을 설정하세요.\n"
|
||||
)
|
||||
|
||||
|
||||
def setup_sensitive():
|
||||
print("\n🔐 Sensitive Data을 설정하시겠습니까?")
|
||||
print("👉 이미 세션을 설정했다면, 이 작업은 **선택사항**입니다.")
|
||||
print("⚠️ 민감 정보 파일은 오류를 유발하거나 문제가 될 수 있으므로 가급적 세션 사용을 권장합니다.")
|
||||
print(
|
||||
"⚠️ 민감 정보 파일은 오류를 유발하거나 문제가 될 수 있으므로 가급적 세션 사용을 권장합니다."
|
||||
)
|
||||
if prompt_yes_no("\033[1m\033[33m선택하시려면 y를 입력하세요 (y/n):\033[0m "):
|
||||
print("======================================================")
|
||||
print("👀 .sensitive.json 파일을 생성합니다.")
|
||||
print("💾 Browser Use의 문서를 참조하여 수정을 수정해주세요.")
|
||||
print("https://docs.browser-use.com/customize/sensitive-data")
|
||||
create_file_from_example('.sensitive.json', '.sensitive.example.json')
|
||||
create_file_from_example(".sensitive.json", ".sensitive.example.json")
|
||||
print("======================================================")
|
||||
print("✅ .sensitive.json 파일이 생성되었습니다.")
|
||||
else:
|
||||
print("🚫 .sensitive.json 생성이 취소되었습니다.")
|
||||
print("======================================================")
|
||||
print("⚠️ 이후에 민감 정보 파일을 설정하려면, .sensitive.example.json 파일을 참고하여 .sensitive.json 파일을 생성하세요.\n")
|
||||
print(
|
||||
"⚠️ 이후에 민감 정보 파일을 설정하려면, .sensitive.example.json 파일을 참고하여 .sensitive.json 파일을 생성하세요.\n"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 1. .env 생성
|
||||
create_file_from_example('.env', '.env.example')
|
||||
create_file_from_example(".env", ".env.example")
|
||||
print("=====================================================")
|
||||
# 2. Playwright용 Chrome 설치
|
||||
install_playwright_chrome()
|
||||
print("=====================================================")
|
||||
|
||||
# 3. Windows 인코딩 문제 해결
|
||||
#i_dont_like_windows()
|
||||
#print("=====================================================")
|
||||
# i_dont_like_windows()
|
||||
# print("=====================================================")
|
||||
|
||||
# 4. Setup User Data
|
||||
asyncio.run(setup_user_data())
|
||||
|
|
|
|||
|
|
@ -181,7 +181,9 @@ async def _run_agent_with_retry(agent_config):
|
|||
return None
|
||||
|
||||
# remove profile
|
||||
if Profile[1]:
|
||||
print(Profile)
|
||||
if Profile[1] and isinstance(Profile[1], str):
|
||||
print(1)
|
||||
shutil.rmtree(Profile[1], ignore_errors=True)
|
||||
print(f"🗑️ 임시 프로필 디렉토리 삭제 완료: {Profile[1]}")
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ async def GetProfile(headless=False):
|
|||
USER_DATA_DIR,
|
||||
tmp_user_data_dir,
|
||||
dirs_exist_ok=False,
|
||||
ignore_dangling_symlinks=True
|
||||
ignore_dangling_symlinks=True,
|
||||
)
|
||||
user_data_dir = tmp_user_data_dir
|
||||
print(f"✅ 사용자 데이터 디렉토리 복사 완료: {user_data_dir}")
|
||||
|
|
@ -61,10 +61,11 @@ async def GetProfile(headless=False):
|
|||
pass
|
||||
tmp_user_data_dir = None
|
||||
user_data_dir = None
|
||||
print(proxy_url)
|
||||
|
||||
profile = BrowserProfile(
|
||||
# Security settings
|
||||
disable_security=True,
|
||||
# disable_security=True,
|
||||
# Display settings
|
||||
headless=headless,
|
||||
# Data persistence
|
||||
|
|
@ -72,11 +73,61 @@ async def GetProfile(headless=False):
|
|||
# Network settings
|
||||
proxy={"server": proxy_url} if proxy_url else None,
|
||||
# Additional arguments
|
||||
args=[
|
||||
"--proxy-server=" + proxy_url if proxy_url else "",
|
||||
# "--disable-features=Translate,PasswordManagerDefaultEnabled",
|
||||
],
|
||||
ignore_default_args=[
|
||||
'--enable-automation',
|
||||
'--disable-extensions',
|
||||
'--hide-scrollbars',
|
||||
'--disable-features=AcceptCHFrame,AutoExpandDetailsElement,AvoidUnnecessaryBeforeUnloadCheckSync,CertificateTransparencyComponentUpdater,DeferRendererTasksAfterInput,DestroyProfileOnBrowserClose,DialMediaRouteProvider,ExtensionManifestV2Disabled,GlobalMediaControls,HttpsUpgrades,ImprovedCookieControls,LazyFrameLoading,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate'
|
||||
"--disable-datasaver-prompt",
|
||||
"--disable-component-extensions-with-background-pages",
|
||||
"--disable-prompt-on-repost",
|
||||
"--safeBrowse-disable-auto-update",
|
||||
"--install-autogenerated-theme=0,0,0",
|
||||
"--disable-speech-synthesis-api",
|
||||
"--ash-no-nudges",
|
||||
"--test-type=gpu",
|
||||
"--noerrdialogs",
|
||||
"--disable-external-intent-requests",
|
||||
"--disable-breakpad",
|
||||
"--disable-backgrounding-occluded-windows",
|
||||
"--export-tagged-pdf",
|
||||
"--disable-focus-on-load",
|
||||
"--suppress-message-center-popups",
|
||||
"--disable-renderer-backgrounding",
|
||||
"--hide-crash-restore-bubble",
|
||||
"--disable-back-forward-cache",
|
||||
"--allow-legacy-extension-manifests",
|
||||
# "--disable-field-trial-config", # 왜 이걸 끄면 웹사이트가 압축된 형태로 보이는 진 모르곘음
|
||||
"--disable-popup-blocking",
|
||||
"--disable-background-networking",
|
||||
"--no-first-run",
|
||||
"--disable-blink-features=AutomationControlled",
|
||||
"--password-store=basic",
|
||||
"--enable-network-information-downlink-max",
|
||||
"--allow-pre-commit-input",
|
||||
"--enable-features=NetworkService,NetworkServiceInProcess",
|
||||
"--metrics-recording-only",
|
||||
"--silent-debugger-extension-api",
|
||||
"--disable-features=AcceptCHFrame,AutoExpandDetailsElement,AvoidUnnecessaryBeforeUnloadCheckSync,CertificateTransparencyComponentUpdater,DestroyProfileOnBrowserClose,DialMediaRouteProvider,ExtensionManifestV2Disabled,GlobalMediaControls,HttpsUpgrades,ImprovedCookieControls,LazyFrameLoading,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate,AutomationControlled,BackForwardCache,OptimizationHints,ProcessPerSiteUpToMainFrameThreshold,InterestFeedContentSuggestions,CalculateNativeWinOcclusion,HeavyAdPrivacyMitigations,PrivacySandboxSettings4,AutofillServerCommunication,CrashReporting,OverscrollHistoryNavigation,InfiniteSessionRestore,ExtensionDisableUnsupportedDeveloper",
|
||||
"--disable-ipc-flooding-protection",
|
||||
"--disable-hang-monitor",
|
||||
"--disable-dev-shm-usage",
|
||||
"--disable-client-side-phishing-detection",
|
||||
"--log-level=2",
|
||||
"--generate-pdf-document-outline",
|
||||
"--disable-speech-api",
|
||||
"--disable-search-engine-choice-screen",
|
||||
"--no-service-autorun",
|
||||
"--no-pings",
|
||||
"--disable-component-update",
|
||||
'--simulate-outdated-no-au="Tue, 31 Dec 2099 23:59:59 GMT"',
|
||||
"--disable-background-timer-throttling",
|
||||
"--use-mock-keychain",
|
||||
"--disable-features=IsolateOrigins,site-per-process",
|
||||
# 아래는 기존 예시에 있던 인자들입니다. 필요에 따라 유지하거나 제거하세요.
|
||||
"--enable-automation",
|
||||
"--disable-extensions",
|
||||
"--hide-scrollbars",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue