browser 模板提供云原生浏览器运行环境,支持通过标准的 Chrome DevTools Protocol(CDP)over WebSocket 远程控制运行在云端隔离容器中的浏览器实例,原生兼容 Puppeteer、Playwright 等自动化框架。
browser 模板不是开通即用的内置模板,需要先从官方 browser 镜像构建一个带名称的自定义模板,再用该模板创建沙箱。本页只介绍能力、默认配置、构建与最小验证、端点差异;BrowserUse、LangChain 等框架接入的完整教程见使用 Browser Use Sandbox。
功能特性
| 特性 | 说明 |
| 浏览器自动化 | 内置 Chromium/Chrome 浏览器,支持完整 Web 标准,原生兼容 Puppeteer、Playwright 等自动化框架 |
| CDP 远程控制 | 通过标准 CDP 协议 over WebSocket 精准操控动态渲染页面(SPA),稳定维持登录态与 Session |
| VNC 实时可视化 | 内置 VNC 服务,支持通过 noVNC 客户端实时查看浏览器桌面环境,方便调试和监控 |
| 安全隔离 | 每个 browser 沙箱实例拥有独立的文件系统和进程空间 |
| 传输加密 | 所有数据面端点(CDP 和 VNC)均使用 WSS(WebSocket Secure)协议,全程加密 |
默认配置
| 配置项 | 默认值 | 说明 |
| 容器镜像 | fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.36 | 预置 browser 镜像 |
| 默认端口 | 3000 | 沙箱服务监听端口 |
| CPU | 4 vCPU | 最低要求 |
| 内存 | 8192 MB | 最低要求 |
| 磁盘大小 | 10240 MB | 建议 10 GB 以获得充足的临时存储空间 |
构建与最小验证
browser 模板的用法分为两个阶段:先构建模板(从 browser 镜像固化出一个带名称的模板),再运行模板(创建沙箱、等待健康检查、通过 CDP 打开页面并截图)。
示例中的 E2B_API_KEY、E2B_API_URL、E2B_DOMAIN 需在运行前通过环境变量(如 .env 或 export)配置为对应地域的接入地址,SDK 会自动读取,无需在方法调用中显式传入。连接 CDP/VNC 端点时需在请求头携带 X-Access-Token:Python SDK 通过内部属性 sbx._envd_access_token 获取(后续版本可能重命名或移除),JS SDK 通过 sbx.envdAccessToken 获取(TypeScript 中为 protected 修饰,运行时可直接读取)。
准备本地环境
Python:
uv venv .venv --python 3.12
source .venv/bin/activate
uv pip install e2b==2.31.0 e2b-code-interpreter==2.8.1 'playwright>=1.49.0'
playwright install chromiumNode.js:使用如下 package.json,然后执行 npm install。
{
"name": "browser-template-demo",
"version": "1.0.0",
"type": "module",
"dependencies": {
"@e2b/code-interpreter": "^2.6.1",
"e2b": "^2.31.0",
"playwright-core": "^1.49.0"
}
}构建 browser 模板
从 browser 镜像构建一个带名称的模板,构建时指定 CPU 与内存规格(推荐 4 vCPU / 8192 MB)。
Python:
"""browser 模板构建示例。"""
import os
from dotenv import load_dotenv
from e2b import Template, default_build_logger
load_dotenv()
# SDK 自动读取 E2B_API_KEY / E2B_API_URL / E2B_DOMAIN 环境变量。
FROM_IMAGE = "fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.36"
build = Template.build(
Template().from_image(FROM_IMAGE),
name="my-browser-template",
cpu_count=4,
memory_mb=8192,
on_build_logs=default_build_logger(),
)
print(f"template_id: {build.template_id}")Node.js:
// browser 模板构建示例。
import { Template, defaultBuildLogger } from 'e2b';
// SDK 自动读取 E2B_API_KEY / E2B_API_URL / E2B_DOMAIN 环境变量。
const FROM_IMAGE =
'fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.36';
const build = await Template.build(Template().fromImage(FROM_IMAGE), 'my-browser-template', {
cpuCount: 4,
memoryMB: 8192,
onBuildLogs: defaultBuildLogger(),
});
console.log(`template_id: ${build.templateId}`);运行模板并验证
创建沙箱后,先轮询 /health 等待 browser 服务就绪,再通过 CDP 端点连接 Playwright 打开目标页并截图。
Python:
"""browser 模板运行示例:创建沙箱 -> 等待健康检查 -> CDP 自动化 -> 截图。"""
import time
from e2b_code_interpreter import Sandbox
from playwright.sync_api import sync_playwright
# SDK 自动读取 E2B_API_KEY / E2B_API_URL / E2B_DOMAIN 环境变量。
BROWSER_PORT = 3000
def wait_until_healthy(sbx: Sandbox, host: str, token: str, timeout: int = 60) -> None:
"""轮询公网网关 /health 端点,直到 browser 服务就绪或超时。"""
token_header = f"-H 'X-Access-Token: {token}' " if token else ""
deadline = time.time() + timeout
while time.time() < deadline:
result = sbx.commands.run(
f"curl -sS -o /dev/null -w '%{{http_code}}' -m 4 {token_header}https://{host}/health",
timeout=10,
)
if "".join(result.stdout or []).strip() == "200":
return
time.sleep(2)
raise TimeoutError(f"browser 服务在 {timeout}s 内未就绪")
sbx = None
try:
sbx = Sandbox.create(template="my-browser-template", timeout=900)
host = sbx.get_host(BROWSER_PORT)
token = sbx._envd_access_token # 公网网关要求 X-Access-Token,否则 403
headers = {"X-Access-Token": token} if token else {}
wait_until_healthy(sbx, host, token)
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(f"wss://{host}/ws/automation", headers=headers)
context = browser.contexts[0] if browser.contexts else browser.new_context()
page = context.new_page()
page.goto("https://example.com", wait_until="domcontentloaded", timeout=30000)
print(f"page.title() = {page.title()!r}")
page.screenshot(path="browser-example.png", full_page=True)
browser.close()
finally:
if sbx is not None:
sbx.kill()Node.js:
// browser 模板运行示例:创建沙箱 -> 等待健康检查 -> CDP 自动化 -> 截图。
import { Sandbox } from '@e2b/code-interpreter';
import { chromium } from 'playwright-core';
// SDK 自动读取 E2B_API_KEY / E2B_API_URL / E2B_DOMAIN 环境变量。
const BROWSER_PORT = 3000;
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
/** 轮询公网网关 /health 端点,直到 browser 服务就绪或超时。 */
async function waitUntilHealthy(sbx, host, token, timeout = 60) {
const tokenHeader = token ? `-H 'X-Access-Token: ${token}' ` : '';
const deadline = Date.now() + timeout * 1000;
while (Date.now() < deadline) {
let result;
try {
result = await sbx.commands.run(
`curl -sS -o /dev/null -w '%{http_code}' -m 4 ${tokenHeader}https://${host}/health`,
{ timeoutMs: 10_000 },
);
} catch (e) {
result = e; // 服务未起时 curl 非 0 退出,异常同样携带 stdout
}
if ((result.stdout || '').trim() === '200') return;
await sleep(2000);
}
throw new Error(`browser 服务在 ${timeout}s 内未就绪`);
}
let sbx = null;
try {
sbx = await Sandbox.create('my-browser-template', { timeoutMs: 900_000 });
const host = sbx.getHost(BROWSER_PORT);
const token = sbx.envdAccessToken; // 公网网关要求 X-Access-Token,否则 403
const headers = token ? { 'X-Access-Token': token } : {};
await waitUntilHealthy(sbx, host, token);
const browser = await chromium.connectOverCDP(`wss://${host}/ws/automation`, { headers });
const contexts = browser.contexts();
const context = contexts.length ? contexts[0] : await browser.newContext();
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded', timeout: 30_000 });
console.log(`page.title() = ${JSON.stringify(await page.title())}`);
await page.screenshot({ path: 'browser-example.png', fullPage: true });
await browser.close();
} finally {
if (sbx !== null) await sbx.kill();
}WebSocket 端点
browser 模板通过 3000 端口暴露以下端点,均需在请求头携带 X-Access-Token 鉴权,<sandbox-host> 通过 SDK 的 sbx.get_host(3000) 获取:
| 端点 | 路径 | 用途 |
| 健康检查 | https://<sandbox-host>/health | 判断 browser 服务是否启动完成 |
| CDP 自动化 | wss://<sandbox-host>/ws/automation | 浏览器自动化,兼容 Puppeteer 和 Playwright |
| VNC 实时流 | wss://<sandbox-host>/ws/livestream | 实时查看浏览器桌面,可通过 noVNC 客户端查看 |
在沙箱内部可先探测 CDP WebSocket 握手是否正常,返回 101 Switching Protocols 即说明端点可升级为 WebSocket:
curl -sS -m 4 -i \
-H 'Connection: Upgrade' -H 'Upgrade: websocket' \
-H 'Sec-WebSocket-Version: 13' -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' \
http://localhost:3000/ws/automation浏览器 WebSocket API 不支持在握手时设置自定义请求头,因此 noVNC 等纯浏览器客户端无法携带 X-Access-Token,直接连接会返回 403。需使用支持自定义请求头的 WebSocket 客户端(如 wscat、Python websockets)携带 X-Access-Token 完成 RFB 握手。如果只需查看结果,可通过 CDP 连接后调用 page.screenshot() 截图。
使用限制
| 限制项 | 约束 |
| 浏览器支持 | 目前内置 Chromium/Chrome 浏览器 |
相关文档
使用 Browser Use Sandbox(BrowserUse、Puppeteer 等框架接入完整教程)
All-In-One 模板示例(需要同时使用浏览器和代码执行能力时选择)