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
146
setup.py
146
setup.py
|
|
@ -6,21 +6,27 @@ from browser_use import BrowserProfile, Agent
|
||||||
from browser_use.llm import ChatGoogle
|
from browser_use.llm import ChatGoogle
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
load_dotenv(verbose=True, override=True)
|
load_dotenv(verbose=True, override=True)
|
||||||
|
|
||||||
os.makedirs(os.path.dirname("./data"), exist_ok=True)
|
os.makedirs(os.path.dirname("./data"), exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
def create_file_from_example(target: str, example: str) -> bool:
|
def create_file_from_example(target: str, example: str) -> bool:
|
||||||
if not os.path.exists(target):
|
if not os.path.exists(target):
|
||||||
if os.path.exists(example):
|
if os.path.exists(example):
|
||||||
with open(example, 'r', encoding='utf-8') as example_file, \
|
with (
|
||||||
open(target, 'w', encoding='utf-8') as target_file:
|
open(example, "r", encoding="utf-8") as example_file,
|
||||||
|
open(target, "w", encoding="utf-8") as target_file,
|
||||||
|
):
|
||||||
target_file.write(example_file.read())
|
target_file.write(example_file.read())
|
||||||
#os.startfile(target)
|
# os.startfile(target)
|
||||||
print(f"✅ {target} 파일이 {example}에서 생성되었습니다.")
|
print(f"✅ {target} 파일이 {example}에서 생성되었습니다.")
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
print(f"⚠️ {example} 파일이 존재하지 않습니다. {target} 생성에 실패했습니다.")
|
print(
|
||||||
|
f"⚠️ {example} 파일이 존재하지 않습니다. {target} 생성에 실패했습니다."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print(f"ℹ️ {target} 파일이 이미 존재합니다.")
|
print(f"ℹ️ {target} 파일이 이미 존재합니다.")
|
||||||
return False
|
return False
|
||||||
|
|
@ -30,7 +36,7 @@ def install_playwright_chrome():
|
||||||
print("\n🛠️ Playwright의 Chromium을 설치 중입니다...")
|
print("\n🛠️ Playwright의 Chromium을 설치 중입니다...")
|
||||||
print("👉 이 작업은 시간이 걸릴 수 있습니다. 잠시 기다려주세요.")
|
print("👉 이 작업은 시간이 걸릴 수 있습니다. 잠시 기다려주세요.")
|
||||||
try:
|
try:
|
||||||
subprocess.run(['uv', 'run', 'playwright', 'install', 'chromium'], check=True)
|
subprocess.run(["uv", "run", "playwright", "install", "chromium"], check=True)
|
||||||
print("✅ Playwright Chrome 설치 완료.")
|
print("✅ Playwright Chrome 설치 완료.")
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
if "already" in e.stdout.decode():
|
if "already" in e.stdout.decode():
|
||||||
|
|
@ -42,23 +48,28 @@ def install_playwright_chrome():
|
||||||
|
|
||||||
def prompt_yes_no(message: str) -> bool:
|
def prompt_yes_no(message: str) -> bool:
|
||||||
print(message, end="")
|
print(message, end="")
|
||||||
return input().strip().lower() in ['y', 'yes']
|
return input().strip().lower() in ["y", "yes"]
|
||||||
|
|
||||||
|
|
||||||
def i_dont_like_windows():
|
def i_dont_like_windows():
|
||||||
# Windows인지 확인
|
# Windows인지 확인
|
||||||
if os.name != 'nt':
|
if os.name != "nt":
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
# run (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage").ACP
|
# run (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage").ACP
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(
|
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,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
check=True
|
check=True,
|
||||||
)
|
)
|
||||||
acp = result.stdout.strip()
|
acp = result.stdout.strip()
|
||||||
if acp == '65001':
|
if acp == "65001":
|
||||||
print("현재 Active Code Page가 UTF-8로 설정되어 있습니다.")
|
print("현재 Active Code Page가 UTF-8로 설정되어 있습니다.")
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
|
@ -68,12 +79,14 @@ def i_dont_like_windows():
|
||||||
print("=======================================================")
|
print("=======================================================")
|
||||||
print("\n⚠️ Windows에서는 인코딩 문제가 발생합니다.")
|
print("\n⚠️ Windows에서는 인코딩 문제가 발생합니다.")
|
||||||
print("👉 엔터를 누르면 자동으로 intl.cpl이 열립니다.")
|
print("👉 엔터를 누르면 자동으로 intl.cpl이 열립니다.")
|
||||||
print("👉 자세한 내용은 README.md에서 \"윈도우 인코딩 해결\"을 참조해주세요.\n")
|
print('👉 자세한 내용은 README.md에서 "윈도우 인코딩 해결"을 참조해주세요.\n')
|
||||||
print("⚠️ 경고 : 이 작업은 윈도우에서 킹갓 대한민국의 프로그램들의 한글이 정상적으로 표시되지 않을 수 있습니다.")
|
print(
|
||||||
|
"⚠️ 경고 : 이 작업은 윈도우에서 킹갓 대한민국의 프로그램들의 한글이 정상적으로 표시되지 않을 수 있습니다."
|
||||||
|
)
|
||||||
# Pause
|
# Pause
|
||||||
input("계속하려면 Enter 키를 누르세요...")
|
input("계속하려면 Enter 키를 누르세요...")
|
||||||
|
|
||||||
webbrowser.open('intl.cpl')
|
webbrowser.open("intl.cpl")
|
||||||
|
|
||||||
print("👉 intl.cpl가 열렸습니다.\n")
|
print("👉 intl.cpl가 열렸습니다.\n")
|
||||||
print("👉 관리자 옵션 -> 시스템 로켈 변경")
|
print("👉 관리자 옵션 -> 시스템 로켈 변경")
|
||||||
|
|
@ -82,7 +95,7 @@ def i_dont_like_windows():
|
||||||
print("⚠️ 이 작업은 시스템 언어 설정을 변경하므로 주의가 필요합니다.\n")
|
print("⚠️ 이 작업은 시스템 언어 설정을 변경하므로 주의가 필요합니다.\n")
|
||||||
print("=======================================================")
|
print("=======================================================")
|
||||||
input("계속하려면 Enter 키를 누르세요...")
|
input("계속하려면 Enter 키를 누르세요...")
|
||||||
|
|
||||||
|
|
||||||
async def setup_user_data():
|
async def setup_user_data():
|
||||||
print("\n📂 사용자 데이터 디렉토리를 설정하시겠습니까?")
|
print("\n📂 사용자 데이터 디렉토리를 설정하시겠습니까?")
|
||||||
|
|
@ -90,15 +103,17 @@ async def setup_user_data():
|
||||||
print("✅ 이 작업은 Google API Key를 설정하고 나서 진행해야만합니다.")
|
print("✅ 이 작업은 Google API Key를 설정하고 나서 진행해야만합니다.")
|
||||||
if prompt_yes_no("\033[1m\033[33m선택하시려면 y를 입력하세요 (y/n):\033[0m "):
|
if prompt_yes_no("\033[1m\033[33m선택하시려면 y를 입력하세요 (y/n):\033[0m "):
|
||||||
if os.getenv("GOOGLE_API_KEY") is None:
|
if os.getenv("GOOGLE_API_KEY") is None:
|
||||||
print("⚠️ Google API Key가 설정되어 있지 않습니다. 먼저 Google API Key를 설정해주세요.")
|
print(
|
||||||
|
"⚠️ Google API Key가 설정되어 있지 않습니다. 먼저 Google API Key를 설정해주세요."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
print("======================================================")
|
print("======================================================")
|
||||||
llm = ChatGoogle(
|
llm = ChatGoogle(
|
||||||
model="gemini-2.0-flash",
|
model="gemini-2.0-flash",
|
||||||
)
|
)
|
||||||
initial_actions = [
|
initial_actions = [
|
||||||
{'go_to_url': {'url': 'https://www.google.com', 'new_tab': False}},
|
{"go_to_url": {"url": "https://www.google.com", "new_tab": False}},
|
||||||
{'wait': {'seconds': 2147483647}},
|
{"wait": {"seconds": 2147483647}},
|
||||||
]
|
]
|
||||||
|
|
||||||
agent = Agent(
|
agent = Agent(
|
||||||
|
|
@ -108,33 +123,90 @@ async def setup_user_data():
|
||||||
initial_actions=initial_actions,
|
initial_actions=initial_actions,
|
||||||
browser_profile=BrowserProfile(
|
browser_profile=BrowserProfile(
|
||||||
disable_security=True,
|
disable_security=True,
|
||||||
#stealth=True,
|
# stealth=True,
|
||||||
headless=False,
|
headless=False,
|
||||||
device_scale_factor=1,
|
device_scale_factor=1,
|
||||||
window_size={"width": 1600, "height": 900},
|
window_size={"width": 1600, "height": 900},
|
||||||
viewport={"width": 1600, "height": 900},
|
viewport={"width": 1600, "height": 900},
|
||||||
user_data_dir="./data/user_data",
|
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("======================================================\n")
|
||||||
print("👉 브라우저가 열립니다. 필요한 로그인을 완료한 후 엔터키를 눌러 다음 단계로 진행하세요.")
|
print(
|
||||||
|
"👉 브라우저가 열립니다. 필요한 로그인을 완료한 후 엔터키를 눌러 다음 단계로 진행하세요."
|
||||||
|
)
|
||||||
input("계속하려면 Enter 키를 누르세요...\n")
|
input("계속하려면 Enter 키를 누르세요...\n")
|
||||||
print("======================================================")
|
print("======================================================")
|
||||||
|
|
||||||
# 브라우저를 백그라운드에서 시작
|
# 브라우저를 백그라운드에서 시작
|
||||||
def run_agent():
|
def run_agent():
|
||||||
asyncio.run(agent.run())
|
asyncio.run(agent.run())
|
||||||
|
|
||||||
agent_thread = threading.Thread(target=run_agent)
|
agent_thread = threading.Thread(target=run_agent)
|
||||||
agent_thread.daemon = True
|
agent_thread.daemon = True
|
||||||
agent_thread.start()
|
agent_thread.start()
|
||||||
|
|
||||||
# 사용자가 'n'을 입력할 때까지 대기
|
# 사용자가 'n'을 입력할 때까지 대기
|
||||||
while True:
|
while True:
|
||||||
user_input = input("").strip().lower()
|
user_input = input("").strip().lower()
|
||||||
if user_input == '':
|
if user_input == "":
|
||||||
|
agent.stop()
|
||||||
break
|
break
|
||||||
|
|
||||||
print("======================================================")
|
print("======================================================")
|
||||||
|
|
@ -142,36 +214,44 @@ async def setup_user_data():
|
||||||
else:
|
else:
|
||||||
print("🚫 설정이 취소되었습니다.")
|
print("🚫 설정이 취소되었습니다.")
|
||||||
print("======================================================")
|
print("======================================================")
|
||||||
print("⚠️ 이후에 USER_DATA_DIR을 설정하려면, .env 파일을 참고하여 USER_DATA_DIR을 설정하세요.\n")
|
print(
|
||||||
|
"⚠️ 이후에 USER_DATA_DIR을 설정하려면, .env 파일을 참고하여 USER_DATA_DIR을 설정하세요.\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup_sensitive():
|
def setup_sensitive():
|
||||||
print("\n🔐 Sensitive Data을 설정하시겠습니까?")
|
print("\n🔐 Sensitive Data을 설정하시겠습니까?")
|
||||||
print("👉 이미 세션을 설정했다면, 이 작업은 **선택사항**입니다.")
|
print("👉 이미 세션을 설정했다면, 이 작업은 **선택사항**입니다.")
|
||||||
print("⚠️ 민감 정보 파일은 오류를 유발하거나 문제가 될 수 있으므로 가급적 세션 사용을 권장합니다.")
|
print(
|
||||||
|
"⚠️ 민감 정보 파일은 오류를 유발하거나 문제가 될 수 있으므로 가급적 세션 사용을 권장합니다."
|
||||||
|
)
|
||||||
if prompt_yes_no("\033[1m\033[33m선택하시려면 y를 입력하세요 (y/n):\033[0m "):
|
if prompt_yes_no("\033[1m\033[33m선택하시려면 y를 입력하세요 (y/n):\033[0m "):
|
||||||
print("======================================================")
|
print("======================================================")
|
||||||
print("👀 .sensitive.json 파일을 생성합니다.")
|
print("👀 .sensitive.json 파일을 생성합니다.")
|
||||||
print("💾 Browser Use의 문서를 참조하여 수정을 수정해주세요.")
|
print("💾 Browser Use의 문서를 참조하여 수정을 수정해주세요.")
|
||||||
print("https://docs.browser-use.com/customize/sensitive-data")
|
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("======================================================")
|
||||||
print("✅ .sensitive.json 파일이 생성되었습니다.")
|
print("✅ .sensitive.json 파일이 생성되었습니다.")
|
||||||
else:
|
else:
|
||||||
print("🚫 .sensitive.json 생성이 취소되었습니다.")
|
print("🚫 .sensitive.json 생성이 취소되었습니다.")
|
||||||
print("======================================================")
|
print("======================================================")
|
||||||
print("⚠️ 이후에 민감 정보 파일을 설정하려면, .sensitive.example.json 파일을 참고하여 .sensitive.json 파일을 생성하세요.\n")
|
print(
|
||||||
|
"⚠️ 이후에 민감 정보 파일을 설정하려면, .sensitive.example.json 파일을 참고하여 .sensitive.json 파일을 생성하세요.\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# 1. .env 생성
|
# 1. .env 생성
|
||||||
create_file_from_example('.env', '.env.example')
|
create_file_from_example(".env", ".env.example")
|
||||||
print("=====================================================")
|
print("=====================================================")
|
||||||
# 2. Playwright용 Chrome 설치
|
# 2. Playwright용 Chrome 설치
|
||||||
install_playwright_chrome()
|
install_playwright_chrome()
|
||||||
print("=====================================================")
|
print("=====================================================")
|
||||||
|
|
||||||
# 3. Windows 인코딩 문제 해결
|
# 3. Windows 인코딩 문제 해결
|
||||||
#i_dont_like_windows()
|
# i_dont_like_windows()
|
||||||
#print("=====================================================")
|
# print("=====================================================")
|
||||||
|
|
||||||
# 4. Setup User Data
|
# 4. Setup User Data
|
||||||
asyncio.run(setup_user_data())
|
asyncio.run(setup_user_data())
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,9 @@ async def _run_agent_with_retry(agent_config):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# remove profile
|
# remove profile
|
||||||
if Profile[1]:
|
print(Profile)
|
||||||
|
if Profile[1] and isinstance(Profile[1], str):
|
||||||
|
print(1)
|
||||||
shutil.rmtree(Profile[1], ignore_errors=True)
|
shutil.rmtree(Profile[1], ignore_errors=True)
|
||||||
print(f"🗑️ 임시 프로필 디렉토리 삭제 완료: {Profile[1]}")
|
print(f"🗑️ 임시 프로필 디렉토리 삭제 완료: {Profile[1]}")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ async def GetProfile(headless=False):
|
||||||
"""브라우저 프로필을 생성하고 임시 사용자 데이터 디렉토리를 관리합니다."""
|
"""브라우저 프로필을 생성하고 임시 사용자 데이터 디렉토리를 관리합니다."""
|
||||||
user_data_dir = None
|
user_data_dir = None
|
||||||
tmp_user_data_dir = None
|
tmp_user_data_dir = None
|
||||||
|
|
||||||
if USER_DATA_DIR and os.path.isdir(USER_DATA_DIR):
|
if USER_DATA_DIR and os.path.isdir(USER_DATA_DIR):
|
||||||
try:
|
try:
|
||||||
tmp_user_data_dir = tempfile.mkdtemp(prefix="browser_use_")
|
tmp_user_data_dir = tempfile.mkdtemp(prefix="browser_use_")
|
||||||
|
|
@ -23,7 +23,7 @@ async def GetProfile(headless=False):
|
||||||
log_file = os.path.join("./data", "userdata.dump")
|
log_file = os.path.join("./data", "userdata.dump")
|
||||||
if not os.path.exists("./data"):
|
if not os.path.exists("./data"):
|
||||||
os.makedirs("./data")
|
os.makedirs("./data")
|
||||||
|
|
||||||
# 기존 로그 파일이 있다면 해당 디렉토리 정리
|
# 기존 로그 파일이 있다면 해당 디렉토리 정리
|
||||||
if os.path.exists(log_file):
|
if os.path.exists(log_file):
|
||||||
try:
|
try:
|
||||||
|
|
@ -35,7 +35,7 @@ async def GetProfile(headless=False):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"⚠️ 이전 임시 디렉토리 정리 실패: {e}")
|
print(f"⚠️ 이전 임시 디렉토리 정리 실패: {e}")
|
||||||
os.remove(log_file)
|
os.remove(log_file)
|
||||||
|
|
||||||
# 새 임시 디렉토리 경로 로깅
|
# 새 임시 디렉토리 경로 로깅
|
||||||
with open(log_file, "w") as f:
|
with open(log_file, "w") as f:
|
||||||
f.write(tmp_user_data_dir)
|
f.write(tmp_user_data_dir)
|
||||||
|
|
@ -44,10 +44,10 @@ async def GetProfile(headless=False):
|
||||||
if os.path.exists(tmp_user_data_dir):
|
if os.path.exists(tmp_user_data_dir):
|
||||||
shutil.rmtree(tmp_user_data_dir)
|
shutil.rmtree(tmp_user_data_dir)
|
||||||
shutil.copytree(
|
shutil.copytree(
|
||||||
USER_DATA_DIR,
|
USER_DATA_DIR,
|
||||||
tmp_user_data_dir,
|
tmp_user_data_dir,
|
||||||
dirs_exist_ok=False,
|
dirs_exist_ok=False,
|
||||||
ignore_dangling_symlinks=True
|
ignore_dangling_symlinks=True,
|
||||||
)
|
)
|
||||||
user_data_dir = tmp_user_data_dir
|
user_data_dir = tmp_user_data_dir
|
||||||
print(f"✅ 사용자 데이터 디렉토리 복사 완료: {user_data_dir}")
|
print(f"✅ 사용자 데이터 디렉토리 복사 완료: {user_data_dir}")
|
||||||
|
|
@ -61,10 +61,11 @@ async def GetProfile(headless=False):
|
||||||
pass
|
pass
|
||||||
tmp_user_data_dir = None
|
tmp_user_data_dir = None
|
||||||
user_data_dir = None
|
user_data_dir = None
|
||||||
|
print(proxy_url)
|
||||||
|
|
||||||
profile = BrowserProfile(
|
profile = BrowserProfile(
|
||||||
# Security settings
|
# Security settings
|
||||||
disable_security=True,
|
# disable_security=True,
|
||||||
# Display settings
|
# Display settings
|
||||||
headless=headless,
|
headless=headless,
|
||||||
# Data persistence
|
# Data persistence
|
||||||
|
|
@ -72,11 +73,61 @@ async def GetProfile(headless=False):
|
||||||
# Network settings
|
# Network settings
|
||||||
proxy={"server": proxy_url} if proxy_url else None,
|
proxy={"server": proxy_url} if proxy_url else None,
|
||||||
# Additional arguments
|
# Additional arguments
|
||||||
|
args=[
|
||||||
|
"--proxy-server=" + proxy_url if proxy_url else "",
|
||||||
|
# "--disable-features=Translate,PasswordManagerDefaultEnabled",
|
||||||
|
],
|
||||||
ignore_default_args=[
|
ignore_default_args=[
|
||||||
'--enable-automation',
|
"--disable-datasaver-prompt",
|
||||||
'--disable-extensions',
|
"--disable-component-extensions-with-background-pages",
|
||||||
'--hide-scrollbars',
|
"--disable-prompt-on-repost",
|
||||||
'--disable-features=AcceptCHFrame,AutoExpandDetailsElement,AvoidUnnecessaryBeforeUnloadCheckSync,CertificateTransparencyComponentUpdater,DeferRendererTasksAfterInput,DestroyProfileOnBrowserClose,DialMediaRouteProvider,ExtensionManifestV2Disabled,GlobalMediaControls,HttpsUpgrades,ImprovedCookieControls,LazyFrameLoading,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate'
|
"--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