尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CubeSandbox 浏览器沙箱实战:在 MicroVM 中运行无头 Chromium 并用 Playwright CDP 远程驱动

CubeSandbox 浏览器沙箱实战:在 MicroVM 中运行无头 Chromium 并用 Playwright CDP 远程驱动 CubeSandbox 浏览器沙箱实战在 MicroVM 中运行无头 Chromium 并用 Playwright CDP 远程驱动【免费下载链接】CubeSandboxInstant, Concurrent, Secure Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox本指南完整讲解 CubeSandbox 官方示例examples/browser-sandbox的实现与用法如何在沙箱镜像启动时以远程调试模式拉起 Chromium如何通过 CubeProxy 把 CDP WebSocket 端点以port-sandbox_id.domain标准 URL 路由出来以及如何用 Python 版 Playwright 从任意机器接入并完成网页抓取、UI 测试、截图与 LLM Agent 浏览任务。读完你将掌握从「创建浏览器模板」到「写出可复用的浏览器自动化脚本」的完整链路并理解其底层路由原理与远程访问的 DNS 配置要点。1. 背景E2B 兼容的浏览器沙箱Cube Sandbox是一个轻量级 MicroVM 平台其控制面与数据面完全兼容 E2B SDK。浏览器沙箱Browser Sandbox是建立在该平台之上的一个开箱即用场景沙箱镜像内预装 Chromium并在系统启动时以远程调试模式remote-debugging在端口9000拉起浏览器进程CubeProxy 负责将 CDP WebSocket 端点通过标准的port-sandbox_id.domainURL 方案路由到正确的虚拟机端口客户端如 Playwright无需在宿主机安装任何浏览器只需通过 CDP 协议挂载到沙箱内已经运行的 Chromium 进程即可。整体数据流如下你的脚本 │ Playwright CDP (WebSocket) ▼ CubeProxy ── https://sandbox_id-9000.domain/cdp? │ ▼ 沙箱 VMChromium端口 90002. 适用场景浏览器沙箱天然适合以下几类工作负载其共同特点是「隔离、一次性、随用随销毁」网页爬取在隔离的一次性环境中进行抓取任务结束销毁沙箱不留宿主机残留自动化 UI 测试对任意网站执行端到端测试无需维护本地浏览器环境截图 / PDF 生成服务作为无头渲染服务按需生成页面截图或 PDFLLM Agent 浏览任务每次 Agent 运行都获得一个全新的浏览器 VM互不干扰天然满足 AI Agent 对沙箱隔离与并发创建的需求。3. 架构与组件┌──────────────────────┐ ┌─────── Cube Sandbox ───────────────┐ │ │ │ │ │ 你的脚本 │ CDP WS │ ┌───────────────────────────┐ │ │ (Playwright Python) │────────►│ │ Chromium --remote-debug │ │ │ │ HTTPS │ │ 端口 9000 │ │ │ │ │ └───────────────────────────┘ │ └──────────────────────┘ │ │ │ CubeProxyTLS 终结 │ └────────────────────────────────────┘组件说明Cube Sandbox从浏览器模板启动的 KVM MicroVMChromium预装启动时带--remote-debugging-port9000CubeProxy将port-sandbox_id.domain路由到对应 VM 端口Playwright通过 CDP 接入宿主机无需安装浏览器3.1 底层路由原理源码佐证port-sandbox_id.domain这段虚拟主机名并非凭空约定而是 CubeProxy 在请求转发阶段实际解析的规则。在 CubeProxy/lua/rewrite_phase.lua 中可以看到其解析逻辑的注释与实现-- Parse Host: container_port-sandbox_id.domain e.g. 49983-7c8fbcd45ffe450fb8f7fb223ad45507.cube.app -- Returns container_port, ins_id (sandbox / instance id), or nil, nil on failure.即 HTTP 请求的Host头中携带容器端口-沙箱ID.域名三段信息CubeProxy 据此把请求精确转发到对应沙箱 VMs 的指定端口。配合 TLS 终结能力客户端只需要一个 HTTPS 的 CDP URL 即可直连沙箱内浏览器这正是「无需任何自定义网络配置」的关键。在 SDK 侧get_host负责生成这段虚拟主机名。见 sdk/python/cubesandbox/sandbox.pydef get_host(self, port: int) - str: Return the virtual hostname for a sandbox port. e.g. 49999-sandboxID.cube.app return f{port}-{self.sandbox_id}.{self.domain}其中域名默认取自CUBE_SANDBOX_DOMAIN环境变量缺省为cube.app见 sdk/python/cubesandbox/_config.py。示例脚本中的https://{sandbox.get_host(9000)}/cdp?最终展开形如https://9000-sandbox_id.cube.app/cdp?。4. 前置条件一套已部署并正常运行的 Cube Sandbox 环境含 CubeAPI、CubeProxy 与计算节点Python 3.8 的客户端机器。安装示例依赖pip install -r requirements.txt playwright install chromium其中requirements.txt见 examples/browser-sandbox/requirements.txt声明的依赖为e2b2.15.2 playwright1.40.0 python-dotenv注意由于 Playwright 通过 CDP 连接的是沙箱内部的 Chromium 进程宿主机上其实不需要真正的 Chromium 二进制这里的playwright install chromium仅用于满足 Playwright Python 包的本地环境检查。5. 快速开始5.1 第一步创建浏览器模板浏览器沙箱以「模板template」为交付单元。使用cubemastercliCubeMaster 的 CLI源码位于 CubeMaster/cmd/cubemastercli/commands/cubebox/template.go从 OCI 镜像一键构建模板cubemastercli tpl create-from-image \ --image cube-sandbox-int.tencentcloudcr.com/cube-sandbox/sandbox-browser:latest \ --writable-layer-size 1G \ --expose-port 9000 \ --probe 9000 \ --probe-path /cdp/json/version # 如果宿主机需要访问外部网络可以添加 --dns dns1 --dns dns2镜像仓库说明境外访问推荐使用cube-sandbox-int.tencentcloudcr.com/cube-sandbox/sandbox-browser:latest如果身处中国大陆请改用cube-sandbox-cn.tencentcloudcr.com/cube-sandbox/sandbox-browser:latest。命令执行成功后请记录输出中的template_id后续创建沙箱时需要用到。关键参数解读依据create-from-image子命令的 flag 定义见 CubeMaster/cmd/cubemastercli/commands/cubebox/template.go参数含义本示例取值--image源 OCI 镜像引用模板构建的根文件系统来源sandbox-browser 镜像--writable-layer-size不可变可写层大小如1G/20Gi必填1G--expose-port模板对外暴露的容器端口可重复指定多个9000--probe在指定端口启用 HTTP GET 就绪探针开启后默认timeout_ms30000、period_ms5009000--probe-path就绪探针的 HTTP 路径默认/health仅在--probe生效/cdp/json/version--dns设置容器 DNS nameserver可重复宿主机需访问外部网络时使用视网络环境--instance-type实例类型默认cubebox默认--network-type网络类型默认tap默认--backendCoW 后端xfs/s3省略时走历史 xfs 路径省略--cpu模板容器 CPU毫核默认2000即 2 核默认--memory模板容器内存MB默认2000默认--with-cube-ca是否将 CubeEgress 根 CA 烘焙进模板根文件系统默认true默认--allow-internet-access/--allow-out-cidr/--deny-out-cidr模板网络策略是否允许外网访问、允许/拒绝出向 CIDR视需要--alias给模板一个稳定的可读别名之后可按别名引用视需要--detach, --no-wait提交后立即退出而不是等待构建完成视需要--json打印原始 JSON 响应视需要其中--probe 9000 --probe-path /cdp/json/version的用意在于模板构建与沙箱创建阶段会通过探针确认 Chromium 的 CDP HTTP 端点已就绪/cdp/json/version是 Chrome DevTools Protocol 的标准版本查询接口避免在浏览器尚未拉起时就交付可用模板。5.2 第二步配置环境变量示例脚本 examples/browser-sandbox/browser.py 会在启动时通过python-dotenv自动加载同目录下的.env文件见load_dotenv(dotenv_pathPath(__file__).with_name(.env), overrideFalse)因此可以准备一个.env写入配置cp .env.example .env # 编辑 .env填写 E2B_API_URL 和 CUBE_TEMPLATE_ID或者直接在 shell 中导出export E2B_API_KEYe2b_000000 export E2B_API_URLhttp://节点IP:3000 export CUBE_TEMPLATE_IDtemplate-id # 配置 mkcert 证书 export NODE_EXTRA_CA_CERTS/root/.local/share/mkcert/rootCA.pem环境变量一览环境变量作用示例值E2B_API_KEY访问 CubeAPI 的鉴权密钥E2B 兼容格式e2b_000000E2B_API_URLCubeAPI 服务地址HTTP 控制面默认 3000 端口http://节点IP:3000CUBE_TEMPLATE_ID第一步创建模板时返回的template_idtemplate-idNODE_EXTRA_CA_CERTS供 Node/Chromium 信任本地 CA 证书如 mkcert 生成的根证书解决 HTTPS 证书校验失败/root/.local/share/mkcert/rootCA.pem5.3 第三步运行示例python browser.py预期输出SandboxInfo(sandbox_id..., template_id..., ...) Home - Tencent第一行是沙箱创建成功后的元信息第二行Home - Tencent说明脚本已成功导航到腾讯官网首页并读到了页面标题即整个「沙箱 → CDP → Playwright → 页面渲染」链路已打通。6. 脚本工作原理示例脚本的核心逻辑见 examples/browser-sandbox/browser.py如下import os from e2b import Sandbox from playwright.sync_api import sync_playwright from dotenv import load_dotenv from pathlib import Path load_dotenv(dotenv_pathPath(__file__).with_name(.env), overrideFalse) os.environ[NODE_NO_WARNINGS] 1 template_id os.environ[CUBE_TEMPLATE_ID] with Sandbox.create(templatetemplate_id) as sandbox: print(sandbox.get_info()) cdp_url fhttps://{sandbox.get_host(9000)}/cdp? # use playwright to operate the browser through cdp_url with sync_playwright() as playwright: browser playwright.chromium.connect_over_cdp(cdp_url) context browser.new_context(ignore_https_errorsTrue) page context.new_page() page.goto(http://www.tencent.com, wait_untildomcontentloaded) print(page.title())其中每个关键步骤的职责如下步骤代码说明1Sandbox.create(template...)从浏览器模板启动新的 MicroVM作为上下文管理器使用退出with块时自动销毁沙箱2sandbox.get_host(9000)解析该沙箱端口 9000 的 CubeProxy URL得到形如9000-sandbox_id.cube.app的虚拟主机名3connect_over_cdp(cdp_url)Playwright 通过 CDP 挂载到沙箱内已运行的 Chromium 进程宿主机无需再启动任何浏览器4page.goto(...)之后即可使用完整的 Playwright API导航、点击、截图、抓取等几点实现细节值得注意cdp_url末尾带?是 CDP over HTTP 端点的标准做法Playwright 会在此基础上建立 WebSocket 连接并协商调试会话browser.new_context(ignore_https_errorsTrue)在沙箱内访问任意 HTTPS 站点时容忍证书问题结合上文的 mkcert CA 配置可进一步消除中间层证书告警page.goto(..., wait_untildomcontentloaded)与page.title()的组合保证脚本拿到的是渲染完成后的真实标题。从 SDK 实现角度看Sandbox.create对应POST /sandboxes接口见 sdk/python/cubesandbox/sandbox.pytemplate参数未显式传入时会回退到CUBE_TEMPLATE_ID环境变量而get_host的实现即上文 3.1 节展示的f{port}-{self.sandbox_id}.{self.domain}。7. 远程访问与 DNS 配置如果 Playwright 脚本运行在与 CubeProxy 不同的机器上即真正的远程访问需要在远程机器上配置cube.app的通配符 DNS 解析将其指向 CubeProxy 的 IP*.cube.app → CubeProxy IP这是因为 Playwright 通过https://9000-sandbox_id.cube.app/cdp?发起连接时操作系统/Node 进程需要解析cube.app域名而它并不是一个公网注册域名必须由你自行解析到 CubeProxy 才能完成 TLS 握手与 WebSocket 连接。重要提醒使用 CubeSandbox SDK 配合CUBE_PROXY_NODE_IP的方式并不会生效。CUBE_PROXY_NODE_IP只对从 CubeSandbox SDK 发出的请求有效——SDK 内部会自动把cube.app域名替换为对应的 proxy IP参见 sdk/python/cubesandbox/_transport.py 中IPOverrideTransport的说明。而浏览器沙箱场景中的连接是由Playwright 的 Node.js 进程发起的网络连接不走 SDK 的传输层替换逻辑因此必须在远程机器上显式配置cube.app的 DNS 解析否则会解析失败。8. 进阶用法完整 Playwright API一旦通过 CDP 挂载成功page对象就拥有 Playwright 的全部能力。以下代码片段可直接复用于你的业务逻辑# 截图 page.screenshot(pathscreenshot.png) # 执行 JavaScript title page.evaluate(document.title) # 等待元素 page.wait_for_selector(#main-content) # 填表并提交 page.fill(input[nameq], cube sandbox) page.press(input[nameq], Enter) page.wait_for_load_state(networkidle)这些操作分别覆盖了页面截图、在页面上下文中执行 JS、等待异步渲染的元素以及模拟用户填表并等待网络空闲四类高频需求。更完整的 API多标签页、拦截请求、下载、录制视频等请参考 Playwright Python 官方文档的Page类说明。9. 常见问题排查现象可能原因解决方法Error: connect ECONNREFUSEDCubeAPI 不可达检查E2B_API_URL及端口 3000 是否开放SSL: CERTIFICATE_VERIFY_FAILEDHTTPS 但未配置 CA 证书设置export NODE_EXTRA_CA_CERTS/root/.local/share/mkcert/rootCA.pemTimeout waiting for CDPChromium 尚未就绪浏览器镜像启动时会拉起 Chromium稍后重试或增大超时Template not found模板 ID 错误重新运行cubemastercli tpl list确认 ID针对最后一类问题也可以使用cubemastercli tpl info template-id查看模板元数据与节点副本状态见 CubeMaster/cmd/cubemastercli/commands/cubebox/template.go确认模板构建是否成功、分布在哪些节点上。10. 目录结构与仓库证据示例目录位于 examples/browser-sandbox结构如下browser-sandbox/ ├── README.md # 英文文档 ├── README_zh.md # 中文文档 ├── browser.py # 示例脚本 ├── requirements.txt # Python 依赖 └── .env.example # 环境变量模板本文涉及的关键仓库证据均可按以下路径深入阅读示例脚本本体examples/browser-sandbox/browser.pyPython 依赖声明examples/browser-sandbox/requirements.txt模板创建 CLI 源码与全部 flag 定义CubeMaster/cmd/cubemastercli/commands/cubebox/template.goSDK 的get_host与Sandbox.create实现sdk/python/cubesandbox/sandbox.pySDK 默认域名与代理 IP 配置sdk/python/cubesandbox/_config.py、sdk/python/cubesandbox/_transport.pyCubeProxy 的port-sandbox_id.domain路由解析CubeProxy/lua/rewrite_phase.lua【免费下载链接】CubeSandboxInstant, Concurrent, Secure Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表