全部產品
Search
文件中心

Function Compute:browser 模板

更新時間:Oct 17, 2026

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.44 預置 browser 鏡像
預設連接埠 3000 沙箱服務監聽連接埠
CPU 4 vCPU 推薦起始規格
記憶體 8192 MB 推薦起始規格
磁碟大小 15360 MB 建議 15 GB 以獲得充足的臨時儲存空間

構建與最小驗證

browser 模板的用法分為兩個階段:先構建模板(從 browser 鏡像固化出一個帶名稱的模板),再運行模板(建立沙箱、等待健全狀態檢查、通過 CDP 開啟頁面並截圖)。

說明

樣本使用北京地區鏡像。其他地區請將鏡像地址中的地區替換為雲沙箱接入地區,並保持版本為 v0.0.44;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 chromium

Node.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.44"

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.44';

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

收到 101 Switching Protocols 後,服務端會繼續發送 WebSocket 資料幀,curl 可能一直等待到 -m 4 逾時並返回退出碼 28。這不表示握手失敗,應以響應中是否包含 101 Switching Protocols 為準。

說明

瀏覽器 WebSocket API 不支援在握手時設定自訂要求標頭,因此 noVNC 等純瀏覽器用戶端無法攜帶 X-Access-Token,直接連接會返回 403。需使用支援自訂要求標頭的 WebSocket 用戶端(如 wscat、Python websockets)攜帶 X-Access-Token 完成 RFB 握手。如果只需查看結果,可通過 CDP 串連後調用 page.screenshot() 截圖。

視窗與螢幕尺寸

browser 鏡像 v0.0.37 起,瀏覽器視窗與虛擬螢幕尺寸由鏡像中的三個環境變數控制:

環境變數 作用 預設值
RESOLUTION Xvfb 虛擬螢幕解析度(寬x高x色深) 1680x1050x24
BROWSER_WINDOW_SIZE Chrome 啟動視窗大小(--window-size) 取 RESOLUTION 的寬高
VNC_CLIP VNC 即時資料流的畫面裁剪地區 與視窗大小一致

Sandbox.create 的 envs 參數只注入沙箱內的命令執行進程,不會影響瀏覽器棧。因此調整視窗尺寸需要先用 Dockerfile 把環境變數烤進自訂鏡像,推送到鏡像倉庫後再通過 from_image 構建模板:

FROM fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.44

ENV RESOLUTION=1920x1080x24
ENV BROWSER_WINDOW_SIZE=1920x1080
ENV VNC_CLIP=1920x1080

構建模板時將 FROM_IMAGE 替換為該自訂鏡像地址即可,其他地區請將鏡像地址中的地區替換為雲沙箱接入地區。視窗尺寸同時決定 VNC 即時資料流的畫面範圍;頁面內視口仍由 Puppeteer、Playwright 等用戶端通過 CDP 自行設定。

使用限制

限制項 約束
瀏覽器支援 目前內建 Chromium/Chrome 瀏覽器

相關文檔