重写browser-use的Browser类加载Chrome扩展时Chromium启动卡顿超时的解决方案
重写browser-use的Browser类加载Chrome扩展时Chromium启动卡顿超时的解决方案
我看了你遇到的麻烦——重写browser-use的Browser类改用launch_persistent_context加载扩展时,Chromium启动超时卡住了。从错误日志和你的代码细节来看,主要是启动参数冲突、扩展加载兼容性、旧缓存干扰这几个问题在搞鬼,咱们一步步来搞定:
1. 解决核心的参数冲突与Headless模式问题
Playwright默认的旧Headless模式完全不支持加载Chrome扩展,而且你的代码里重复添加了大量启动参数,直接导致启动阻塞。需要做这些调整:
- 改用新Headless模式(如果需要无头运行)
- 移除重复的扩展、安全参数,避免和Playwright默认参数冲突
- 添加规避证书、GPU错误的参数,解决日志里的NSS和GPU报错
2. 清理用户数据目录,消除旧缓存干扰
之前的用户数据目录可能残留了旧的扩展缓存或配置,导致服务工作者启动失败(日志里的DidStartWorkerFail错误),每次启动前清空目录就能解决这个问题。
3. 延长启动超时时间
扩展加载需要额外时间,默认的180秒可能不够,把超时时间调到5分钟会更稳妥。
修改后的完整CustomBrowser类代码
import asyncio import os import shutil from browser_use import Agent, BrowserConfig, Browser from browser_use.browser.browser import logger from langchain_openai import ChatOpenAI from playwright.async_api import async_playwright, Playwright extension_path = "/path/to/capsolver-extension" class CustomBrowser(Browser): async def _setup_browser(self, playwright: Playwright): """Sets up and returns a Playwright Browser instance with persistent context.""" if self.config.wss_url: browser = await playwright.chromium.connect(self.config.wss_url) return browser elif self.config.chrome_instance_path: import subprocess import requests try: # Check if browser is already running response = requests.get('http://localhost:9222/json/version', timeout=2) if response.status_code == 200: logger.info('Reusing existing Chrome instance') browser = await playwright.chromium.connect_over_cdp( endpoint_url='http://localhost:9222', timeout=20000, # 20 second timeout for connection ) return browser except requests.ConnectionError: logger.debug('No existing Chrome instance found, starting a new one') # Start a new Chrome instance subprocess.Popen( [ self.config.chrome_instance_path, '--remote-debugging-port=9222', ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) # Attempt to connect again after starting a new instance try: browser = await playwright.chromium.connect_over_cdp( endpoint_url='http://localhost:9222', timeout=20000, # 20 second timeout for connection ) return browser except Exception as e: logger.error(f'Failed to start a new Chrome instance.: {str(e)}') raise RuntimeError( ' To start chrome in Debug mode, you need to close all existing Chrome instances and try again otherwise we can not connect to the instance.' ) else: try: disable_security_args = [] if self.config.disable_security: disable_security_args = [ '--disable-web-security', '--disable-site-isolation-trials', '--disable-features=IsolateOrigins,site-per-process', ] # 使用全新的用户数据目录,每次启动前清空旧数据 user_data_dir = os.path.join(os.getcwd(), "fresh_user_data") if os.path.exists(user_data_dir): shutil.rmtree(user_data_dir) os.makedirs(user_data_dir, exist_ok=True) # 整理启动参数,移除重复项,添加必要的兼容参数 launch_args = [ '--no-sandbox', '--disable-blink-features=AutomationControlled', '--disable-infobars', '--disable-background-timer-throttling', '--disable-popup-blocking', '--disable-backgrounding-occluded-windows', '--disable-renderer-backgrounding', '--disable-window-activation', '--disable-focus-on-load', '--no-first-run', '--no-default-browser-check', '--window-position=0,0', # 扩展加载参数,直接在这里配置,避免重复 f"--disable-extensions-except={extension_path}", f'--load-extension={extension_path}', # 解决证书和GPU启动错误 '--ignore-certificate-errors', '--disable-gpu', '--disable-software-rasterizer', ] + disable_security_args # 启动持久化上下文,使用新Headless模式(如果需要),延长超时 browser_context = await playwright.chromium.launch_persistent_context( user_data_dir=user_data_dir, # 旧Headless不支持扩展,改用新Headless模式 headless="new" if self.config.headless else False, args=launch_args, proxy=self.config.proxy, timeout=300000, # 5分钟超时,给扩展足够加载时间 accept_downloads=True, ) # 返回上下文,确保Agent能正常调用new_page等方法 return browser_context except Exception as e: logger.error(f'Failed to initialize Playwright browser: {str(e)}') raise # 简化配置,不需要在extra_chromium_args里重复加参数 config = BrowserConfig( headless=False, # 先测试非Headless模式,确认扩展能加载后再改回new Headless disable_security=True # 按需开启,不需要的话可以设为False ) browser = CustomBrowser(config=config) async def main(): agent = Agent( task="Go to Reddit, search for 'browser-use' in the search bar, click on the first post and return the first comment.", llm=ChatOpenAI(model="gpt-4o"), browser=browser, ) result = await agent.run() print(result) asyncio.run(main())
额外注意事项
- 确保
extension_path指向的是包含manifest.json的扩展根目录,路径一定要准确 - 先测试非Headless模式(
headless=False),确认扩展能正常加载后,再尝试新Headless模式(headless="new") - 如果还是有问题,检查你的扩展是否兼容Playwright当前使用的Chromium版本,可以运行
playwright install chromium更新到最新兼容版本
备注:内容来源于stack exchange,提问作者Benjamin Geoffrey




