You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

重写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

火山引擎 最新活动