沙箱Browser-Use场景使用

更新时间:
复制 MD 格式

本文介绍如何在RDS Supabase沙箱中使用Browser-Use(浏览器自动化)能力,通过e2b-code-interpreter SDK结合Chrome DevTools Protocol(CDP)驱动AI Agent直接操作浏览器DOM,涵盖4个典型使用场景。

前提条件

  • 已创建RDS Supabase实例,且实例处于运行中状态。

  • 实例所在地域为华北2(北京)、华东2(上海)、华东1(杭州)、华南1(深圳)或西南1(成都)。

  • 已完成关联角色AliyunServiceRoleForRDSAISupabase授权。

  • 已在RDS控制台的沙箱和边缘函数页面启用沙箱功能。具体操作,请参见使用沙箱和边缘函数

使用限制

  • Browser-Use仅面向浏览器场景,直接操作浏览器DOM,不支持任意桌面应用,桌面场景请使用沙箱Computer-Use场景使用

  • 沙箱默认超时时长为3600秒,可通过timeout参数调整,超时后需重新创建。

配置Browser-Use

依次完成以下6个配置项,准备Browser-Use运行环境。

步骤一:创建steel-browser沙箱模板

RDS Supabase实例详情页创建steel-browser公共模板,并记录模板ID供后续代码使用。

  1. 在实例详情页左侧导航栏,选择组件 > 沙箱和边缘函数

  2. 确认启用沙箱和边缘函数开关已开启。

  3. 沙箱模板区域,单击模板市场

  4. 在右侧弹出的模板市场面板中,找到模板名称列为steel-browser描述列为Image used in browser-use scenarios.的行,单击该行操作列的创建

  5. 创建完成后返回沙箱模板列表,找到配置项steel-browser的行,复制模板ID列的完整值,格式为steel-browser-<6位随机后缀>。此模板ID将作为后续代码中Sandbox.create(template="<模板id>")参数的取值,请妥善保存。

步骤二:绑定域名

Supabase实例的IP地址绑定域名。

  1. 在实例详情页中获取实例的外网连接地址对应的IP地址。

  2. 在本地/etc/hosts文件中添加域名映射记录。本文以<实例ID>.sb.rds.com为示例域名:

    <实例IP地址> <实例ID>.sb.rds.com
说明

开发测试场景建议直接写入/etc/hosts;生产环境请使用DNS解析。

步骤三:下载e2b SDKpatch代码

GitHub仓库下载e2b SDKpatch代码,该patch用于适配RDS Supabase的路由方式。

步骤四:(可选)配置SSL实现HTTPS访问

如需通过HTTPS访问沙箱,请先为Supabase实例配置SSL证书。配置SSL后,设置以下环境变量:

# rootCA.pem为生成Supabase实例SSL证书对应的CA证书
export SSL_CERT_FILE="/xxx/rootCA.pem"
export REQUESTS_CA_BUNDLE="/xxx/rootCA.pem"
说明

后续Python代码中调用patch_e2b()方法即表示对e2b SDK进行patch,其入参TrueFalse表示是否使用HTTPS访问沙箱。传入True时使用HTTPS,此时需先为RDS Supabase实例开通HTTPS,并参见使用沙箱和边缘函数文档设置HTTPS相关的环境变量;传入False时使用HTTP访问。

步骤五:配置环境变量

设置以下环境变量,用于e2b SDK连接Supabase实例、以及AI Agent调用大模型:

# E2B_DOMAIN:步骤二:绑定域名中绑定的域名
export E2B_DOMAIN=<实例ID>.sb.rds.com

# E2B_API_KEY:Supabase实例的Service Key
export E2B_API_KEY=<your_service_key>

# LLM_API_KEY:大模型API密钥(如通义千问、OpenAI等OpenAI兼容接口)
export LLM_API_KEY=<your_llm_api_key>

# LLM_BASE_URL:大模型API基础URL
export LLM_BASE_URL=<your_llm_base_url>

Service Key获取路径:在实例详情页右上角,单击获取API Key,在弹出的对话框中复制ServiceKey的值。

说明

Browser-Use场景由AI Agent直接驱动浏览器,需要调用大模型完成任务分析与决策,因此必须配置LLM_API_KEYLLM_BASE_URLLLM_BASE_URL需指向OpenAI兼容的接口地址(如通义千问兼容模式)。

步骤六:安装依赖

执行以下命令安装Browser-Use SDK及沙箱运行时:

pip install browser-use e2b-code-interpreter

Browser-Use使用示例

Browser-Use的核心工作流程依次为:接收用户指令、创建浏览器沙箱、通过CDP连接浏览器、AI Agent解析页面DOM、执行操作(点击/输入/导航等),并循环直至任务完成。与Computer-Use的截图、视觉分析、操控模式不同,Browser-Use直接操作浏览器DOM,执行更精准、速度更快。以下4个使用场景各自提供一份完整可运行的Python脚本,复制后按运行示例代码的说明保存为.py文件即可执行。

场景一:基础网页浏览与信息提取

AI Agent自主访问指定网页并提取关键信息,是Browser-Use最基础的使用形态。

import asyncio
import json
import os

from browser_use import Agent, BrowserSession
from browser_use.llm import ChatOpenAI
from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b

# 未配置SSL时传False;已在配置Browser-Use步骤四配置SSL时改为True
patch_e2b(False)


async def get_cdp_url(sbx, debug_port: int = 9222, proxy_port: int = 9223) -> str:
    """从沙箱内查询Chromium的CDP WebSocket URL。

    Chromium在沙箱内监听debug_port(默认9222),通过 curl 拿到
    webSocketDebuggerUrl,再通过 sbx.get_host(proxy_port) 映射为外部可达地址。
    """
    result = sbx.commands.run(f'curl -s http://127.0.0.1:{debug_port}/json/version')
    if not result.stdout.strip():
        raise Exception("获取CDP URL失败,请确认Chromium已在沙箱内启动")
    version_info = json.loads(result.stdout)
    ws_path = version_info['webSocketDebuggerUrl'].split('/', 3)[-1]
    return f"ws://{sbx.get_host(proxy_port)}/{ws_path}"


async def main():
    # 使用配置Browser-Use步骤一记录的steel-browser模板ID创建沙箱
    sandbox = Sandbox.create(template="<模板id>", timeout=3600)
    try:
        cdp_url = await get_cdp_url(sandbox)
        browser_session = BrowserSession(
            cdp_url=cdp_url,
            headers={"X-API-Key": os.getenv('E2B_API_KEY')},
        )
        await browser_session.start()

        agent = Agent(
            task="访问阿里云官网,找到RDS Supabase的产品介绍页面,总结其主要功能。",
            llm=ChatOpenAI(
                api_key=os.getenv("LLM_API_KEY"),
                base_url=os.getenv("LLM_BASE_URL"),
                model="qwen3-vl-plus",
                temperature=1,
            ),
            browser_session=browser_session,
        )
        result = await agent.run()
        print(f"任务结果: {result}")

        await browser_session.close()
    finally:
        sandbox.kill()


asyncio.run(main())

场景二:表单填写与提交

AI Agent自动填写网页表单并提交。任务描述通过多行字符串给出结构化指令,便于AI理解字段与操作对应关系;温度设为0提升字段填写的确定性。

import asyncio
import json
import os

from browser_use import Agent, BrowserSession
from browser_use.llm import ChatOpenAI
from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b

patch_e2b(False)


async def get_cdp_url(sbx, debug_port: int = 9222, proxy_port: int = 9223) -> str:
    result = sbx.commands.run(f'curl -s http://127.0.0.1:{debug_port}/json/version')
    if not result.stdout.strip():
        raise Exception("获取CDP URL失败,请确认Chromium已在沙箱内启动")
    version_info = json.loads(result.stdout)
    ws_path = version_info['webSocketDebuggerUrl'].split('/', 3)[-1]
    return f"ws://{sbx.get_host(proxy_port)}/{ws_path}"


async def main():
    sandbox = Sandbox.create(template="<模板id>", timeout=3600)
    try:
        cdp_url = await get_cdp_url(sandbox)
        browser_session = BrowserSession(
            cdp_url=cdp_url,
            headers={"X-API-Key": os.getenv('E2B_API_KEY')},
        )
        await browser_session.start()

        agent = Agent(
            task="""
            打开 https://example.com/contact 页面,
            在姓名栏填写 "张三",
            在邮箱栏填写 "zhangsan@example.com",
            在留言栏填写 "你好,这是一条测试消息",
            然后点击提交按钮。
            """,
            llm=ChatOpenAI(
                api_key=os.getenv("LLM_API_KEY"),
                base_url=os.getenv("LLM_BASE_URL"),
                model="qwen3-vl-plus",
                temperature=0,   # 表单类任务用0温度,减少随机性
            ),
            browser_session=browser_session,
        )
        result = await agent.run()
        print(f"表单提交结果: {result}")

        await browser_session.close()
    finally:
        sandbox.kill()


asyncio.run(main())
说明

表单类任务对确定性要求高,建议将temperature设为0,避免模型输出偏差影响字段填写。

场景三:多步骤复杂任务

AI Agent可以处理包含搜索、筛选、对比等多步骤的复杂浏览任务。任务描述用有序列表结构化多步骤指令,AI会按顺序执行。

import asyncio
import json
import os

from browser_use import Agent, BrowserSession
from browser_use.llm import ChatOpenAI
from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b

patch_e2b(False)


async def get_cdp_url(sbx, debug_port: int = 9222, proxy_port: int = 9223) -> str:
    result = sbx.commands.run(f'curl -s http://127.0.0.1:{debug_port}/json/version')
    if not result.stdout.strip():
        raise Exception("获取CDP URL失败,请确认Chromium已在沙箱内启动")
    version_info = json.loads(result.stdout)
    ws_path = version_info['webSocketDebuggerUrl'].split('/', 3)[-1]
    return f"ws://{sbx.get_host(proxy_port)}/{ws_path}"


async def main():
    sandbox = Sandbox.create(template="<模板id>", timeout=3600)
    try:
        cdp_url = await get_cdp_url(sandbox)
        browser_session = BrowserSession(
            cdp_url=cdp_url,
            headers={"X-API-Key": os.getenv('E2B_API_KEY')},
        )
        await browser_session.start()

        agent = Agent(
            task="""
            1. 打开百度搜索 "RDS Supabase"
            2. 记录前3条搜索结果的标题和摘要
            3. 然后点击第一条结果进入详情页
            4. 总结该页面的核心内容
            """,
            llm=ChatOpenAI(
                api_key=os.getenv("LLM_API_KEY"),
                base_url=os.getenv("LLM_BASE_URL"),
                model="qwen3-vl-plus",
                temperature=1,
            ),
            browser_session=browser_session,
        )
        result = await agent.run()
        print(f"多步骤任务结果: {result}")

        await browser_session.close()
    finally:
        sandbox.kill()


asyncio.run(main())

场景四:带截图回调的Agent

通过on_step_end回调在每一步结束后截取页面截图,脚本会自动在当前目录创建./screenshots/目录并按Unix时间戳保存每步截图,便于调试和审计。

import asyncio
import base64
import json
import os
import time

from browser_use import Agent, BrowserSession
from browser_use.llm import ChatOpenAI
from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b

patch_e2b(False)


async def get_cdp_url(sbx, debug_port: int = 9222, proxy_port: int = 9223) -> str:
    result = sbx.commands.run(f'curl -s http://127.0.0.1:{debug_port}/json/version')
    if not result.stdout.strip():
        raise Exception("获取CDP URL失败,请确认Chromium已在沙箱内启动")
    version_info = json.loads(result.stdout)
    ws_path = version_info['webSocketDebuggerUrl'].split('/', 3)[-1]
    return f"ws://{sbx.get_host(proxy_port)}/{ws_path}"


async def screenshot(agent: Agent):
    """每步结束后截取浏览器页面截图并保存到 ./screenshots/ 目录。"""
    try:
        page = await agent.browser_session.get_current_page()
        if page is None:
            print("截图跳过: 当前无可用页面")
            return
        b64_data = await page.screenshot(format='png')
        screenshots_dir = os.path.join(".", "screenshots")
        os.makedirs(screenshots_dir, exist_ok=True)
        screenshot_path = os.path.join(screenshots_dir, f"{time.time()}.png")
        with open(screenshot_path, "wb") as f:
            f.write(base64.b64decode(b64_data))
        print(f"截图已保存至 {screenshot_path}")
    except Exception as e:
        print(f"截图失败: {e}")


async def main():
    sandbox = Sandbox.create(template="<模板id>", timeout=3600)
    try:
        cdp_url = await get_cdp_url(sandbox)
        browser_session = BrowserSession(
            cdp_url=cdp_url,
            headers={"X-API-Key": os.getenv('E2B_API_KEY')},
        )
        await browser_session.start()

        agent = Agent(
            task="访问阿里云官网,找到RDS Supabase的产品介绍页面,总结其主要功能。",
            llm=ChatOpenAI(
                api_key=os.getenv("LLM_API_KEY"),
                base_url=os.getenv("LLM_BASE_URL"),
                model="qwen3-vl-plus",
                temperature=1,
            ),
            browser_session=browser_session,
        )
        # 每一步执行后自动截图
        await agent.run(on_step_end=screenshot)

        await browser_session.close()
    finally:
        sandbox.kill()


asyncio.run(main())

运行示例代码

完成前面6个配置步骤后,按以下流程运行本文中的Python示例。

步骤一:创建脚本文件

将示例代码保存为.py文件,必须与配置Browser-Use步骤三下载的patch_e2b源码放在同一目录,否则会报ModuleNotFoundError: No module named 'patch_e2b'。目录结构示例:

e2b-sdk-patch/
├── patch_e2b/          # 配置Browser-Use步骤三下载的patch源码
└── demo.py             # 您的示例脚本

如需将脚本放在其他目录,请将patch_e2b源码路径加入PYTHONPATH

export PYTHONPATH="/path/to/e2b-sdk-patch:$PYTHONPATH"
说明

其中/path/to/e2b-sdk-patch为占位符,需替换为本地patch_e2b源码所在的实际绝对路径(例如/Users/yourname/code/e2b-sdk-patch);:$PYTHONPATH用于保留原有路径,避免覆盖。设置完成后,在同一终端窗口中运行脚本即可生效。

步骤二:替换代码中的占位符

示例代码中的<模板id>需替换为配置Browser-Use步骤一记录的模板ID(格式为steel-browser-<后缀>)。

步骤三:确认环境变量已生效

在运行脚本的终端中执行以下命令,确认配置Browser-Use步骤五配置的4个环境变量已加载:

echo $E2B_DOMAIN     # 应输出 <实例ID>.sb.rds.com
echo $E2B_API_KEY    # 应输出 Supabase ServiceKey
echo $LLM_API_KEY    # 应输出 大模型API密钥
echo $LLM_BASE_URL   # 应输出 大模型API基础URL

步骤四:运行脚本

python3 demo.py

常见启动问题

Q1:报错ModuleNotFoundError: No module named 'patch_e2b'怎么办?

A:脚本不在patch_e2b源码目录,请将脚本移动到patch源码目录,或配置PYTHONPATH环境变量指向patch源码路径。

Q2:报错ModuleNotFoundError: No module named 'browser_use'No module named 'e2b_code_interpreter'怎么办?

A:未安装Browser-Use SDK,请执行pip install browser-use e2b-code-interpreter

Q3:CDP连接失败或超时怎么办?

A:可能原因包括:

  • /etc/hosts未配置域名映射,请检查配置Browser-Use步骤二。

  • E2B_DOMAIN环境变量未设置或与/etc/hosts不一致,请检查配置Browser-Use步骤五。

  • 沙箱内Chromium未正常启动,请重新Sandbox.create并等待几秒后重试。

Q4:报错401认证失败怎么办?

A:E2B_API_KEY错误,请在实例详情页右上角单击获取API Key重新获取ServiceKey并更新环境变量。

Q5:AI Agent无响应或输出乱码怎么办?

A:请检查LLM_API_KEYLLM_BASE_URL是否正确,以及model参数指定的模型名是否在您的账号可用范围内;另可尝试将temperature调低以稳定输出。

相关文档