mirror of
https://github.com/j93es/browser-use-oauth.git
synced 2026-06-04 05:51:52 +09:00
[Enhancement] async_playwright 추가 및 OAuth 로그인 흐름 개선, Planner 제외 (오히려 문제가 일어남)
This commit is contained in:
parent
1474399f5c
commit
9b797a8d21
2 changed files with 49 additions and 12 deletions
|
|
@ -3,7 +3,7 @@ ANONYMIZED_TELEMETRY=false
|
|||
GOOGLE_API_KEY=
|
||||
# 권장 (다른 모델로 교체 가능) [다른 모델로 교체시 성능 보장 불가]
|
||||
GOOGLE_MODEL=gemini-2.5-flash-preview-05-20
|
||||
GOOGLE_PLANNER_MODEL=gemini-2.5-flash-preview-05-20
|
||||
#GOOGLE_PLANNER_MODEL=gemini-2.5-flash-preview-05-20
|
||||
|
||||
# min(INITIAL_BACKOFF * (2 ** try_cnt), MAX_BACKOFF)만큼 API가 실패시 대기합니다.
|
||||
INITIAL_BACKOFF=60
|
||||
|
|
@ -17,6 +17,9 @@ BACKEND_URL=http://localhost:11081
|
|||
# 브라우저 언어 설정
|
||||
LANG=en_US
|
||||
|
||||
# 필수 뒤에 있는 이메일 주소는 Google 계정의 로그인 힌트로 사용됩니다.
|
||||
# 이메일의 전체를 입력해주세요
|
||||
GOOGLE_ID=bot.imnya.ng@gmail.com
|
||||
|
||||
# provider 계정 (본인이 사용하지 않는 계정 권장) (Github, apple, kakao등 다른 계정 추가 가능)
|
||||
# PROVIDOR_CREDENTIALS_IN_LLM는 True로 설정시, 아래 계정 정보가 LLM에 포함되어 사용됩니다.
|
||||
|
|
|
|||
48
main.py
48
main.py
|
|
@ -17,6 +17,7 @@ from browser_use import (
|
|||
BrowserProfile,
|
||||
Controller,
|
||||
)
|
||||
from patchright.async_api import async_playwright as async_patchright
|
||||
from lib.is_html import is_html_url
|
||||
from lib.read_txt import read_lines_between
|
||||
from lib.prompt import extend_planner_system_message
|
||||
|
|
@ -39,11 +40,12 @@ backend_url = os.getenv("BACKEND_URL", "http://localhost:11081")
|
|||
|
||||
print("🔧 환경 설정:")
|
||||
print(f"🔗 Backend URL: {backend_url}")
|
||||
api_key = os.getenv('GOOGLE_API_KEY')
|
||||
api_key = os.getenv("GOOGLE_API_KEY")
|
||||
print(f"🔑 Google API Key: {api_key[-4:] if api_key else None}")
|
||||
print(f"🌐 Google Model: {os.getenv('GOOGLE_MODEL')}")
|
||||
print(f"🌐 Google Planner Model: {os.getenv('GOOGLE_PLANNER_MODEL')}")
|
||||
|
||||
|
||||
# API 쿼터 처리를 위한 콜백 핸들러
|
||||
class QuotaExhaustedHandler(BaseCallbackHandler):
|
||||
def on_llm_error(self, error, **kwargs):
|
||||
|
|
@ -156,7 +158,9 @@ async def scan_one_url(url: str, skip_html_check: bool = False):
|
|||
if storage_state_path.exists():
|
||||
if storage_state_temp_path.exists():
|
||||
storage_state_temp_path.unlink()
|
||||
storage_state_temp_path.write_text(storage_state_path.read_text(), encoding="utf-8")
|
||||
storage_state_temp_path.write_text(
|
||||
storage_state_path.read_text(), encoding="utf-8"
|
||||
)
|
||||
print(f"🔄 Using existing storage state: {storage_state_temp_path}")
|
||||
else:
|
||||
storage_state_temp_path = None
|
||||
|
|
@ -164,11 +168,17 @@ async def scan_one_url(url: str, skip_html_check: bool = False):
|
|||
# BrowserProfile에 모든 설정 포함
|
||||
profile = BrowserProfile(
|
||||
disable_security=True,
|
||||
deterministic_rendering=True,
|
||||
stealth=True,
|
||||
headless=False,
|
||||
# user_data_dir=str(user_data_path),
|
||||
user_data_dir=None,
|
||||
storage_state=str(storage_state_temp_path) if storage_state_temp_path and storage_state_temp_path.exists() else None,
|
||||
executable_path="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
||||
storage_state=(
|
||||
str(storage_state_temp_path)
|
||||
if storage_state_temp_path and storage_state_temp_path.exists()
|
||||
else None
|
||||
),
|
||||
viewport={"width": 1600, "height": 900},
|
||||
# 프록시 설정
|
||||
proxy={"server": proxy_url} if proxy_url else None,
|
||||
|
|
@ -184,11 +194,23 @@ async def scan_one_url(url: str, skip_html_check: bool = False):
|
|||
"--ignore-certificate-errors",
|
||||
"--ignore-ssl-errors",
|
||||
"--allow-running-insecure-content",
|
||||
"--disable-web-security",
|
||||
"--disable-features=VizDisplayCompositor",
|
||||
"--disable-blink-features=AutomationControlled",
|
||||
"--no-first-run",
|
||||
"--no-service-autorun",
|
||||
"--password-store=basic",
|
||||
"--use-mock-keychain",
|
||||
"--no-default-browser-check",
|
||||
"--disable-extensions-file-access-check",
|
||||
"--disable-extensions-http-throttling",
|
||||
"--disable-component-extensions-with-background-pages",
|
||||
],
|
||||
)
|
||||
|
||||
# BrowserSession에 profile 전달
|
||||
session = BrowserSession(
|
||||
playwright=(await async_patchright().start()),
|
||||
browser_profile=profile,
|
||||
)
|
||||
|
||||
|
|
@ -200,9 +222,19 @@ async def scan_one_url(url: str, skip_html_check: bool = False):
|
|||
agent = Agent(
|
||||
browser_session=session,
|
||||
initial_actions=initial_actions,
|
||||
task="Navigate to the login page, and collect the OAuth provider buttons and their login URLs. Ignore Passkey.",
|
||||
llm=CreateChatGoogleGenerativeAI(os.getenv("GOOGLE_MODEL") or "fallback"),
|
||||
planner_llm=CreateChatGoogleGenerativeAI(os.getenv("GOOGLE_PLANNER_MODEL") or "fallback"),
|
||||
task=(
|
||||
"Navigate to the login page, identify all OAuth provider buttons (excluding Passkey), "
|
||||
"and for each one: click the button, follow the full OAuth login flow as far as possible "
|
||||
"with a real user account (without using a fake or non-existent account), and capture the "
|
||||
"final redirect URL after login. Do not stop at just collecting the initial authorization URL—"
|
||||
"actually perform the login step like a real user would. "
|
||||
"If the OAuth buttons do not appear immediately, wait briefly to allow the page to load completely before proceeding. "
|
||||
"Always log out before starting the login process, and make sure to attempt the login again from a clean state."
|
||||
),
|
||||
llm=CreateChatGoogleGenerativeAI(
|
||||
os.getenv("GOOGLE_MODEL") or "fallback"
|
||||
),
|
||||
# planner_llm=CreateChatGoogleGenerativeAI(os.getenv("GOOGLE_PLANNER_MODEL") or "fallback"),
|
||||
controller=controller,
|
||||
extend_planner_system_message=extend_planner_system_message(),
|
||||
)
|
||||
|
|
@ -245,7 +277,9 @@ async def scan_one_url(url: str, skip_html_check: bool = False):
|
|||
print("🔐 Detected OAuth Providers and URLs:")
|
||||
for entry in oauth_entries:
|
||||
if "<" in entry.oauth_uri or "..." in entry.oauth_uri:
|
||||
print(f"⚠️ WARNING: {entry.provider} URL may be masked or incomplete:\n{entry.oauth_uri}\n")
|
||||
print(
|
||||
f"⚠️ WARNING: {entry.provider} URL may be masked or incomplete:\n{entry.oauth_uri}\n"
|
||||
)
|
||||
else:
|
||||
print(f"- {entry.provider}: {entry.oauth_uri}")
|
||||
print("-" * 50)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue