Files
skill-template/examples/real_browser_rpa/scripts/service/browser_session.py
chendelian b267ca3266
All checks were successful
技能自动化发布 / release (push) Successful in 7s
chore: auto release commit (2026-06-15 17:32:47)
2026-06-15 17:32:49 +08:00

136 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""浏览器会话启动(系统 Chrome/Edge + Playwright persistent context"""
from __future__ import annotations
import logging
import os
from typing import Any, Optional, Tuple
from util.constants import DEFAULT_START_URL
logger = logging.getLogger(__name__)
DEFAULT_PAGE_TIMEOUT_MS = 15_000
GOTO_TIMEOUT_MS = 60_000
STEALTH_INIT_SCRIPT = """
(() => {
try { Object.defineProperty(navigator, 'webdriver', { get: () => undefined }); } catch (e) {}
})();
"""
def get_start_url() -> str:
return (os.getenv("TARGET_START_URL") or DEFAULT_START_URL).strip() or DEFAULT_START_URL
def _headless_from_env() -> bool:
v = (os.getenv("OPENCLAW_BROWSER_HEADLESS") or "0").strip().lower()
return v in ("1", "true", "yes", "on")
def _find_chrome_executable() -> str | None:
try:
from jiangchang_skill_core.runtime_env import find_chrome_executable
chrome = find_chrome_executable()
if chrome and os.path.isfile(chrome):
return chrome
except ImportError:
pass
candidates = [
os.path.expandvars(r"%ProgramFiles%\Google\Chrome\Application\chrome.exe"),
os.path.expandvars(r"%ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe"),
os.path.expandvars(r"%ProgramFiles%\Microsoft\Edge\Application\msedge.exe"),
os.path.expandvars(r"%ProgramFiles(x86)%\Microsoft\Edge\Application\msedge.exe"),
]
for path in candidates:
if path and os.path.isfile(path):
return path
return None
async def start_browser_session(
profile_dir: str,
*,
headless: Optional[bool] = None,
) -> Tuple[Any, Any, Any]:
"""
启动持久化 Chrome profilenew_page + goto 入口页,返回 (playwright, context, page)。
真实 skill 需要安装 playwright 与 jiangchang_skill_core。
"""
from playwright.async_api import async_playwright
hl = headless if headless is not None else _headless_from_env()
start_url = get_start_url()
chrome = _find_chrome_executable()
if not chrome:
raise RuntimeError(
"ERROR:MISSING_BROWSER 未检测到 Chrome 或 Edge 浏览器,请先安装系统浏览器后重试。"
)
launch_args = ["--start-maximized", "--disable-blink-features=AutomationControlled"]
logger.info(
"browser_launch chrome=%s profile_dir=%s start_url=%s args=%s headless=%s",
chrome,
profile_dir,
start_url,
launch_args,
hl,
)
print(f"[浏览器] 系统 Chrome: {chrome}")
print(f"[浏览器] profile_dir: [{profile_dir}]")
print(f"[浏览器] startup_url={start_url}")
print(f"[浏览器] args={launch_args}")
pw = await async_playwright().start()
context = None
try:
context = await pw.chromium.launch_persistent_context(
user_data_dir=profile_dir,
headless=hl,
executable_path=chrome,
locale="zh-CN",
no_viewport=True,
args=launch_args,
ignore_default_args=["--enable-automation"],
)
await context.add_init_script(STEALTH_INIT_SCRIPT)
page = await context.new_page()
page.set_default_timeout(DEFAULT_PAGE_TIMEOUT_MS)
try:
await page.goto(start_url, wait_until="domcontentloaded", timeout=GOTO_TIMEOUT_MS)
except Exception as exc:
raise RuntimeError(
f"浏览器已启动,但未能打开目标首页 {start_url}"
"请检查网络、Chrome profile、代理或页面访问状态。"
f"{exc}"
) from exc
return pw, context, page
except Exception:
if context is not None:
try:
await context.close()
except Exception:
pass
await pw.stop()
raise
async def close_browser_context(pw, context) -> None:
try:
if context is not None:
await context.close()
except Exception:
pass
try:
if pw is not None:
await pw.stop()
except Exception:
pass