Cloudflare Browser Run 能力范围、运行原理与使用方式
AI 参与说明(Agent:Codex):本文根据 Cloudflare Browser Run 官方文档辅助整理,覆盖产品能力、协议、API、会话管理和费用边界。资料核验日期为 2026-10-20;未取得任务级模型与 reasoning effort 运行记录。
资料与修订记录
2026-10-30(Agent:Codex):通过 Context7 的 Browser Run 独立索引发现文档,并核对官方原始页面;补充端点选择、异步抓取示例、超时与缓存、会话清理和故障处理。保留创建日期与 canonical URL。执行入口 Codex;未取得任务级完整模型标识与 reasoning effort 运行记录。
Browser Run 可以为应用和 Agent 提供远程 Chrome,完成网页提取、自动化操作、实时观看和人工接管。一次性输出适合 Quick Actions,连续交互适合 Browser Sessions;需要完整 Linux 桌面时,应使用 Containers 或 Sandboxes。
| 英文术语 | 中文名称 | 简要解释 |
|---|---|---|
| Browser Run | Browser Run | Cloudflare 托管的远程 Chrome 服务,原名 Browser Rendering。 |
| Quick Actions | 快捷操作 | 用一次请求完成截图、PDF 或内容提取等常见任务。 |
| Browser Sessions | 浏览器会话 | 保留浏览器实例,通过多个命令完成有状态的交互。 |
| Chrome DevTools Protocol(CDP) | Chrome 开发者工具协议 | Chrome DevTools 使用的远程控制协议,可导航、检查和操作网页。 |
| Live View | 实时视图 | 在浏览器中观看并操作远程页面的托管界面。 |
| Human in the Loop | 人工参与 | 自动化遇到需要人工判断或输入的步骤时,把操作交给人,再恢复自动化。 |
| Browser Context | 浏览器上下文 | 同一浏览器中的独立状态空间,用于隔离 Cookie、缓存和本地存储。 |
| Guardrails | 访问限制 | 约束会话能够访问的 HTTP 和 HTTPS 主机名。 |
什么时候需要 Browser Run
截图服务、网页转 PDF、抓取动态页面、浏览器测试和网页 Agent,都需要真正运行网页 JavaScript 的浏览器。Browser Run 把 Chrome 的启动、托管和服务接入交给 Cloudflare,应用通过 API 操作它。它既能返回一次截图,也能维持一个有多个标签页的会话,让 Agent 连续操作,并让人实时观看和接管。
只需要一次截图或页面内容,用 Quick Actions;需要登录、搜索、填写表单或跨页操作,用 Browser Sessions。完整 Linux 桌面、终端和任意原生软件则属于 Containers 或 Sandboxes 的范围。Browser Run 总览
Browser Run 的产品定位是托管浏览器执行层:应用把 URL、HTML 或自动化命令交给服务,取得页面内容或操作结果。它与普通 HTTP fetch() 的区别在于能够运行网页 JavaScript、维护页面状态并模拟交互;与自建 Chrome 的区别在于浏览器基础设施由平台管理。只读静态 HTML 时,先考虑普通 HTTP 请求,避免为无需渲染的任务启动浏览器。/crawl 另提供 render: false 的非渲染模式。
Browser Run executes Chrome remotely. Your application controls it through APIs; Chrome does not run inside the Worker isolate.
部署时,Worker 可以保存业务逻辑、鉴权和任务路由,Chrome 在远程浏览器服务中运行。应用也可以放在本地脚本、CI 或其他服务器上,通过 CDP 连接同一个服务,不要求把整个后端迁到 Cloudflare。CDP
Quick Actions 与 Browser Sessions
| 需求 | 选择 | 需要编写的逻辑 |
|---|---|---|
| 网页截图、生成 PDF | Quick Actions | 指定 URL 或 HTML、输出和等待参数。 |
| 获取 HTML、Markdown、链接或指定元素 | Quick Actions | 描述要提取的内容。 |
| 按提示或 Schema 提取结构化数据 | Quick Actions /json | 给出任务及结果约束,评估提取结果。 |
| 批量发现并抓取网站页面 | Quick Actions /crawl | 提交异步任务、查询结果和处理逐页状态。 |
| 登录后执行多步操作 | Browser Sessions | 导航、定位元素、输入、等待和失败处理。 |
| Agent 自动浏览并展示操作过程 | Browser Sessions | Agent 工具、会话协调和 Live View。 |
| 浏览器端测试 | Browser Sessions | Playwright 或 Puppeteer 脚本及断言。 |
Quick Actions 目前包含 /content、/screenshot、/pdf、/markdown、/snapshot、/accessibilityTree、/scrape、/json、/links 和 /crawl。其中 /snapshot 是一次采集多种页面输出的接口,不是保存浏览器进程或容器磁盘。/crawl 仅支持 REST API,其他 Quick Actions 也可以经 Worker 的 env.BROWSER.quickAction() 调用。Quick Actions
Quick Actions 端点速查
| 端点 | 主要输出 | 选择时注意 |
|---|---|---|
/content | JavaScript 执行后的 HTML | 适合需要完整 DOM 的后续解析。 |
/screenshot、/pdf | 图片、PDF | 二进制响应应保存为文件;PDF 另有生成超时。 |
/markdown | Markdown | 适合阅读、索引与模型输入;不能代替页面交互。 |
/links、/scrape | 链接、CSS selector 匹配结果 | 已知页面结构时优先使用确定性提取。 |
/json | 按提示或 JSON Schema 提取的数据 | 使用 AI;Schema 约束不等于事实正确,结果仍需校验。 |
/snapshot | 同一页面的多种格式 | 减少重复请求,不保存会话供后续接管。 |
/accessibilityTree | 页面无障碍树 | 帮助理解角色与可访问名称,不等同于完整 DOM。 |
/crawl | 多页 HTML、Markdown 或 JSON | 异步任务;REST only,需要查询结果与逐页状态。 |
各端点的参数和响应形式不同,不能将截图的二进制响应当成 JSON,也不能假设所有操作都返回同一种 result。Quick Actions 目录
Browser Sessions 可以通过 Puppeteer、Playwright、CDP、Stagehand 或 MCP 集成控制。标准脚本适合操作路径明确的任务;AI 方式可以帮助理解意图和选择元素,但页面状态判断、结果核验和失败恢复仍属于应用逻辑。服务提供浏览器,不自动替应用完成业务任务。接入选择
一次请求怎样变成浏览器操作
Quick Actions 把常见操作封装成 HTTP 请求,平台管理浏览器资源和输出。Browser Sessions 则把会话管理与具体操作分开:HTTP 接口用于创建、查询和关闭会话,CDP WebSocket 用于向浏览器发送命令并接收事件。
flowchart TD
APP["应用或 Agent"] --> CHOICE{"是否需要连续交互"}
CHOICE -->|否| QUICK["Quick Actions HTTP 或 Worker Binding"]
CHOICE -->|是| SESSION["创建或复用 Browser Session"]
QUICK --> OUTPUT["截图 PDF HTML Markdown JSON"]
SESSION --> CDP["CDP WebSocket"]
CDP --> CHROME["远程 Chrome 与多个标签页"]
CHROME --> SITE["目标网站"]
CHROME --> LIVE["Live View"]
HUMAN["用户"] -->|观看或操作| LIVE
CDP 与 Chrome DevTools 使用同一套协议。Puppeteer 和 Playwright 把导航、元素定位、截图等操作封装成高层 API;开发者也可以直接发送 CDP 命令。一个 Browser Session 对应一个远程 Chrome 实例,可以包含多个标签页。CDP 使用 target 表示可调试对象,页面 target 通常对应一个标签页。CDP 原理
Worker 内的 browser binding 还提供 acquire()、connectSession()、launch()、listSessions()、closeSession() 和 devtools 等类型化接口。这里 binding 的 launch() 返回供 CDP 客户端连接的对象,与 @cloudflare/playwright 返回高层 Browser 对象的 launch() 不应混为一谈。Browser binding API
三种最小接入方式
以下示例依据官方接口整理,没有调用真实 Cloudflare 账户执行。REST 和外部 Node.js 示例需要账户 ID,以及具有 Browser Run 编辑权限的 API Token;部分文档或控制台仍使用旧名称 Browser Rendering - Edit。Worker binding 示例不需要把账户 API Token 写进代码。
用 REST 截图
准备 ACCOUNT_ID 和 CLOUDFLARE_API_TOKEN 环境变量后执行:
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/browser-run/screenshot" \
--fail-with-body \
--request POST \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{"url":"https://example.com"}' \
--output screenshot.png
预期得到 screenshot.png。接口接受 url 或 html,还支持 viewport、整页截图、指定元素、Cookie、HTTP Basic Auth、自定义请求头和等待参数。动态页面应等待目标元素或业务状态,不要仅凭页面开始加载就认定内容已完整渲染。/screenshot 参数
产品更名后,当前端点使用 /browser-run。部分旧示例仍保留 /browser-rendering,SDK 也可能保留 browserRendering 属性。阅读时应按具体接口文档核对路径和字段,避免只替换显示名称便假设所有标识同步更名。
从 Node.js 使用 Playwright
这条路线适合已有 Node.js 后端、脚本和 CI。安装不附带本地浏览器的 playwright-core:
npm install playwright-core
把以下内容保存为 browser-run.mjs。环境变量使用 CF_ACCOUNT_ID 和 CF_API_TOKEN:
import { chromium } from "playwright-core";
const accountId = process.env.CF_ACCOUNT_ID;
const apiToken = process.env.CF_API_TOKEN;
if (!accountId || !apiToken) {
throw new Error("Set CF_ACCOUNT_ID and CF_API_TOKEN before running.");
}
const base =
`https://api.cloudflare.com/client/v4/accounts/${accountId}/browser-run`;
const headers = { Authorization: `Bearer ${apiToken}` };
const acquired = await fetch(`${base}/devtools/browser?keep_alive=600000`, {
method: "POST",
headers
});
if (!acquired.ok) throw new Error(`Acquire failed: ${acquired.status}`);
const session = await acquired.json();
if (typeof session.sessionId !== "string") {
throw new Error("Acquire response did not include a sessionId.");
}
const endpoint = session.webSocketDebuggerUrl ??
`${base.replace("https:", "wss:")}/devtools/browser/${session.sessionId}`;
let browser;
try {
browser = await chromium.connectOverCDP(endpoint, {
headers
});
const context = browser.contexts()[0] ?? await browser.newContext();
const page = context.pages()[0] ?? await context.newPage();
await page.goto("https://example.com");
console.log(await page.title());
await page.screenshot({ path: "screenshot.png" });
} finally {
try {
if (browser) await browser.close();
} finally {
const closed = await fetch(`${base}/devtools/browser/${session.sessionId}`, {
method: "DELETE",
headers
});
if (!closed.ok && closed.status !== 404) {
throw new Error(`Close failed: ${closed.status}`);
}
}
}
运行 node browser-run.mjs,预期打印页面标题并保存截图。创建接口直接返回 sessionId 和可选的 webSocketDebuggerUrl,不使用通用 result 封套。此例结束时既关闭客户端,也通过 HTTP DELETE 结束服务端会话;如果会话已经关闭而返回 404,则视为已释放。浏览器操作发生在远程 Chrome,本地只运行控制逻辑。Playwright over CDP、HTTP 会话管理、创建接口响应
在 Worker 中启动 Browser Session
Worker 内使用适配 Cloudflare 的 @cloudflare/playwright:
npm create cloudflare@latest -- browser-run-demo
cd browser-run-demo
npm install @cloudflare/playwright
创建项目时选择 Worker 和 TypeScript。将 wrangler.jsonc 中对应配置设为:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "browser-run-demo",
"main": "src/index.ts",
"compatibility_date": "2026-10-20",
"compatibility_flags": ["nodejs_compat"],
"browser": {
"binding": "BROWSER",
"remote": true
}
}
src/index.ts:
import { launch } from "@cloudflare/playwright";
interface Env {
BROWSER: Fetcher;
}
export default {
async fetch(_request: Request, env: Env): Promise<Response> {
const browser = await launch(env.BROWSER);
try {
const page = await browser.newPage();
await page.goto("https://example.com");
return Response.json({ title: await page.title() });
} finally {
await browser.close();
}
}
} satisfies ExportedHandler<Env>;
运行 npx wrangler dev,访问本地 Worker 地址,预期返回包含标题的 JSON。remote: true 让本地控制逻辑连接真实远程服务,因此会消耗浏览器额度。确认行为后可用 npx wrangler deploy 部署。Workers Playwright
若任务只是截图,不需要安装 Playwright,可以让 Worker 直接返回 Quick Actions 响应:
export default {
async fetch(_request, env) {
return env.BROWSER.quickAction("screenshot", {
url: "https://example.com"
});
}
};
quickAction() 要求 compatibility date 至少为 2026-03-24,本地使用 remote: true 或 wrangler dev --remote。它管理操作所需的会话,不需要应用自行保存 Session ID。Quick Actions binding
接入已有 Agent
已有 MCP 客户端可以通过 chrome-devtools-mcp 接入 Browser Run。MCP server 将工具调用转换为 CDP 命令,Agent 因而能够导航、截图、检查 Console 和调用相应调试工具。配置中的 --wsEndpoint 指向 Browser Run,--wsHeaders 提供服务端认证;Token 不应进入网页前端或公开配置。
通过现成的工具适配层,可以先验证 Agent 能否完成真实网页任务。需要自定义操作权限、并发协调或人工交接时,再在应用侧补充任务状态与控制逻辑。MCP 连接本身不提供业务授权,也不保证网页操作结果正确。MCP 接入
Live View 与 Human in the Loop
Live View 提供三种界面:tab 展示并控制单个页面,full 展示浏览器界面和打开的标签页,devtools 展示 Elements、Console 等调试面板。可从控制台、REST 或 CDP 获取 devtoolsFrontendUrl。默认五分钟有效期约束开始连接的时间,可扩展至一小时;已经建立的连接可以在会话仍存活时继续使用。
链接包含签名 JWT,拿到完整链接的人就可能获得对应访问能力。只读入口可以通过 REST 的 guardrails: { mode: "readonly" } 生成,但只限制该连接;Agent 通过其他连接仍能操作会话。API Token 始终留在可信服务端。Live View
已有会话时,可用下面的请求生成入口。SESSION_ID 必须来自当前应用拥有并允许该用户访问的会话:
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/browser-run/devtools/browser/$SESSION_ID/live_view" \
--fail-with-body \
--request POST \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--json '{"mode":"tab","expiresInMs":300000}'
应用取得响应中的 devtoolsFrontendUrl 后,可把它展示为用户入口。服务端生成链接前仍需验证会话归属;链接持有者的访问能力不能替代应用的用户鉴权。
Human in the Loop 在此基础上增加交接状态。应用可以等待人工登录、输入敏感信息或检查结果,再决定是否继续。结构化交接的顺序如下:
sequenceDiagram
participant A as Agent 控制程序
participant B as Browser Session
participant H as 用户
A->>B: 订阅 Cloudflare.handoffComplete
A->>B: Cloudflare.getLiveView mode tab
B-->>A: 返回 devtoolsFrontendUrl
A-->>H: 展示操作入口与所需任务
A->>B: Cloudflare.handoff instructions timeout
H->>B: 打开 Live View 并执行操作
H->>B: 选择 Done 或 Failed
B-->>A: handoffComplete success reason
alt 人工步骤成功
A->>B: 验证页面状态并继续
else 失败或超时
A->>A: 记录原因并结束或转人工处理
end
要先订阅完成事件,再发起 Cloudflare.handoff,避免漏掉快速完成的结果。结构化交接只支持 mode: "tab";timeout 显式设置时最大 30 分钟,不设置则没有这一层交接超时,浏览器本身仍受会话生命周期约束。用户点击 Done 是继续处理的信号,涉及业务结果时仍应核验页面状态。Human in the Loop
Live View、Human in the Loop 和 Session Recording 当前均标为 Beta。依赖这些功能上线时,应把它们的状态变化和异常恢复纳入应用设计,不能仅凭能生成一个观看链接就认定完整协作流程已经完成。
Session Recording 与调试
Session Recording 使用 rrweb 捕获 DOM 变化、鼠标键盘事件和导航,产物是 JSON 事件,适合回放和检查自动化过程。它不等同于连续屏幕录像,也不应被当成所有视觉内容都能完整还原的保证。
Session recording stores structured browser events, not a video stream.
录制必须在首次获取会话时启用:SDK 使用 recording: true,CDP URL 使用 recording=true。重连已有会话时不能补开。会话结束后才完成录制,可在控制台 Browser Run 的 Runs 中回放,也可用 Session ID 访问 /browser-run/recording/{session_id}。刚结束时可能尚在整理并暂时返回 404,应按文档重试。Session Recording
Playwright trace 是另一种调试材料,包含操作、页面快照、截图和控制台信息,可以生成 trace.zip 用于 Trace Viewer。它与平台 Session Recording 的入口、产物和使用方式不同;应按排查目标选择,不要将两者混称为视频。Playwright Trace
会话复用与长期状态
默认空闲超时为 60 秒,keep_alive 可以延长到 20 分钟。持续活跃的会话没有固定最大生命周期,但服务升级仍可能关闭会话。
The keep_alive option sets an inactivity timeout, not a maximum session lifetime.
十分钟的 keep_alive 不代表任务只能运行十分钟,也不代表浏览器状态已经持久化。复用时保存 Session ID,重连前检查会话是否存在;失效后重新创建,并从应用保存的进度恢复。任务完成后若不再复用,应明确关闭会话,否则等待空闲超时的时间仍会消耗额度。Limits
多个标签页复用同一个浏览器实例并共享资源预算,页面过重或标签页过多仍可能使会话不稳定。Browser Context 可以隔离 Cookie、缓存和存储,但不承诺进程或容器隔离。共享会话能减少创建次数和冷启动,适合可信任务池;需要独立配置或更强隔离时,应使用不同会话并核对平台的隔离保证。Durable Object 可以路由同一任务的请求并协调冲突,但其持久化存储不会让远程 Chrome 的内存跨重启保存。Reuse Sessions、FAQ
登录状态也应显式管理。Playwright 可以导出 storageState 并在新 Context 中恢复,官方示例将 Cookie、localStorage 和 IndexedDB 状态存入 KV。应按用户和任务隔离这些数据,并把它们视为具有账户访问能力的敏感材料;保存结果文件和任务进度则可用 R2、Durable Objects 等产品。Storage State
共享会话时如何清理
上面的独占会话示例在任务结束后关闭整个 browser。共享会话池则应让每次请求创建自己的 Browser Context,结束时关闭 Context,再断开该请求的 CDP 连接。Cloudflare SDK 的 browser.disconnect() 保留远程浏览器;browser.close() 会结束整个共享会话并断开所有客户端。不要直接把独占会话示例的清理逻辑复制到共享池。
Cloudflare 的多连接复用要求 @cloudflare/playwright 至少为 1.3.0,或 @cloudflare/puppeteer 至少为 1.1.0。列出会话与重连之间仍可能发生会话关闭,应用要处理这一竞争条件;Browser Context 只隔离页面状态,不协调关闭浏览器等全局操作。Reuse Sessions
工程上可以在 Durable Object 中保存任务进度、Session ID 和协调状态,但每次重连仍需确认浏览器存活。把“已提交任务”“已完成业务步骤”“已保存产物”分别落盘,浏览器丢失后才知道从哪里继续。表单提交、下单等操作在重试前要先确认是否已成功,避免重复副作用。这些是应用侧的恢复设计,不是 Browser Run 自动提供的事务保证。
网络访问与 Guardrails
Session Guardrails 限制 Browser Session 的 HTTP 和 HTTPS 主机名,启动时确定,并在整个会话中保持不变。allowedDomains 最多 50 条,allowedDomainSets 最多 4 个;省略两者表示不限制,空 allowedDomains: [] 则禁止外部 HTTP/HTTPS。页面可能依赖第三方脚本、CDN、字体、API 和登录跳转,这些域名也必须纳入策略。
Guardrails 当前是 Beta,且不适用于 Quick Actions。它约束整个会话的目标主机,Live View 的 readonly 只约束一个观看连接,两者不能互相替代。Guardrails
需要访问受控私有服务时,可以通过 outboundByHost 把指定主机名的浏览器请求交给 service binding 连接的 Worker。该 Worker 再补充认证、访问目标服务或转换响应;目标主机名不要求有公网 DNS。它提供了受控路由入口,不表示 Browser Run 默认能直连任意内网地址。Outbound Workers
Browser Run 请求带有不可移除的来源标识和 Web Bot Auth 签名。更换 User-Agent 不会隐藏身份;人工接管也不会把它变成普通用户设备的网络请求。目标网站可能仍阻止访问,服务不提供绕过 CAPTCHA、Turnstile 或其他机器人保护的保证,也不支持逐请求 IP 轮换。Automatic Request Headers、FAQ
抓取网站时的额外约束
/crawl 是异步网站抓取入口,会从起始 URL、sitemap 和页面链接发现内容。它遵守 robots.txt、crawl-delay 和 Content Signals;没有指定 crawl-delay 时,同域请求默认间隔 0.5 秒。禁止抓取的 URL 会在结果中标记状态,任务完成也不代表每一页都成功。
当前 /crawl 的 crawlPurposes 和 contentUse 会影响任务能否启动。crawlPurposes 使用 search、ai-input、ai-train,默认声明全部三项。目标站点允许搜索、禁止训练,而实际任务只建立搜索索引时,应声明 crawlPurposes: ["search"];若还要把内容送入模型,则必须按实际用途声明并满足对应限制。
contentUse 接受 reference 或 full,默认 full,用于声明内容使用层级。站点要求 use=reference 时,默认 full 会被拒绝,需按实际用途设为 reference;站点要求 use=immediate 时,所有 /crawl 请求都会被拒绝,因为该接口保留抓取结果,不接受即时、无留存用途。用途声明不能替代业务许可;上述执行行为属于 /crawl,不应推广为所有 CDP 命令统一具有的策略。/crawl 行为
提交与查询一次 crawl
下面使用 Bash、curl 和 jq,沿用前文的账户环境变量。示例将用途限定为搜索索引;若用于模型输入或训练,应改为实际用途。它最多抓取 10 页、链接深度 2,使用默认的浏览器渲染模式:
CRAWL_BASE="https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/browser-run/crawl"
JOB_ID=$(curl "$CRAWL_BASE" --fail-with-body --request POST \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{"url":"https://example.com/","limit":10,"depth":2,"formats":["markdown"],"crawlPurposes":["search"],"contentUse":"reference"}' \
| jq -er 'select(.success == true) | .result | strings') || exit 1
printf 'Crawl job: %s\n' "$JOB_ID"
# 间隔一段时间重复此请求,直到 result.status 不再是 running。
curl "$CRAWL_BASE/$JOB_ID?limit=1" --fail-with-body \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
| jq '.result | {status, total, finished}'
# 任务结束后读取结果;有 cursor 时继续分页,不能只保存第一页。
curl "$CRAWL_BASE/$JOB_ID" --fail-with-body \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--output crawl-results.json
POST 返回 result 中的 job ID,而不是抓取内容。GET 中的 job completed 也不意味着所有记录都成功;应检查 records 的 completed、disallowed、skipped、errored 等状态。需要取消任务时,对同一 /$JOB_ID 地址发 DELETE。crawl 生命周期与响应
Crawl jobs can run for up to seven days. Results remain available for 14 days after completion.
因此要及时将所需结果保存到自己的存储。结果超过 10 MB 时,接口返回 cursor 供后续分页。POST 的 limit 控制要抓取多少页;GET 的 limit 控制一次读取多少条记录,二者作用不同。Workers Free 另限每日 5 个任务、每任务最多 100 页;通用 API 的 100,000 页参数上限不覆盖免费计划限制。Crawl limits
render: false 只获取 HTML,不执行网页 JavaScript,适合服务器已经输出正文的页面;当前文档称该模式在 Beta 期间不计浏览器费用,不能据此假设长期免费或其他相关服务也免费。该模式只支持 crawl 专属参数;Cookie、额外请求头、资源拦截等标准浏览器参数适用于 render: true。crawl 参数
超时、缓存与数据留存
Quick Actions 的页面加载、等待元素与生成结果分别有计时器,不应把所有超时都归因于会话的 60 秒空闲限制:
| 阶段 | 默认值或行为 | 最大值 |
|---|---|---|
| 页面导航 timeout | 30 秒 | 60 秒 |
| 导航完成条件 | domcontentloaded | 按任务选择加载事件或网络空闲条件 |
waitForSelector | 默认未设置 | 60 秒 |
waitForTimeout | 默认未设置 | 60 秒 |
actionTimeout | 默认未设置 | 5 分钟 |
| PDF 生成 timeout | 30 秒 | 5 分钟 |
配置时核对具体端点的 gotoOptions 等字段及大小写;不要把 SDK 的选项名和 REST 参数任意互换。对于持续请求数据的页面,网络空闲不一定能出现,应优先等待明确的业务元素或状态。422 也可能出现在生成截图或 PDF 阶段,单纯增加导航 timeout 不一定有效。Quick Actions timeouts
除 /crawl 外,Quick Actions 默认缓存输出 5 秒,cacheTTL 可以设为 0 禁用,最长为 86,400 秒。需要实时内容或登录后内容时,应明确决定是否禁用缓存。/crawl 有独立的 maxAge 与结果保留规则;Session Recording 是主动开启的录制,保留 30 天,不属于普通内容缓存。不要因为浏览器会话已经关闭,就认定所有服务端产物都已删除。数据与缓存 FAQ
限额与费用怎样估算
以下为核验日期的默认技术限额,不等于包含额度:
| 项目 | Workers Free | Workers Paid |
|---|---|---|
| 浏览器时间 | 每日 10 分钟 | 无固定用量上限,按价格计费 |
| Browser Sessions 并发实例 | 3 | 200,可申请提高 |
| 新浏览器创建速率 | 每 20 秒 1 个 | 每秒 3 个 |
| Quick Actions 请求速率 | 每 10 秒 1 个 | 每秒 30 个 |
| 默认空闲超时 | 60 秒 | 60 秒 |
浏览器实例和创建速率按实例统计,打开更多标签页不会增加这两项计数,但会增加同一会话的资源压力。200 是技术并发上限,不能理解为付费套餐免费包含 200 个并发。Limits
Workers Paid 每月包含 10 browser-hours,超出部分为 0.09 美元每小时。Browser Sessions 另按每日峰值并发的月平均数计费,包含 10 个,超过部分每个每月 2 美元。Quick Actions 不收取并发费;Worker、存储、AI 提取和模型等产品的费用仍需分别计算。Pricing
假设一个月使用 100 browser-hours,且每日峰值并发的月平均数为 15,超额浏览器时间为 (100 − 10) × 0.09 = 8.10 美元,并发超额为 (15 − 10) × 2 = 10 美元,合计 18.10 美元,尚未包含上述其他产品费用。这是便于复算的假设,不是任意 15 并发任务的固定报价。
人工等待也占用活跃会话,长 keep_alive 会延长闲置资源释放时间。应用应同时观察 browser-hours、峰值并发和任务成功率。Quick Actions 响应的 X-Browser-Ms-Used 可用于统计单次浏览器耗时,再用真实任务样本估算单位成本。Quick Actions 用量
常见失败怎样定位
| 现象 | 优先检查 | 应对方式 |
|---|---|---|
quickAction 方法不存在 | compatibility date、本地是否启用 remote binding | 按前文配置;本地调试连接远程服务会消耗额度。 |
| 达到速率或并发限制 | 创建速率、Quick Actions 速率与当前活跃会话 | 排队并限制并发;按响应退避,减少无效重建。 |
| 页面打开但输出空白 | 数据是否在 DOM 事件之后才出现、selector 是否匹配 | 等待实际业务状态,检查导航与提取各阶段。 |
| 重连失效 | 空闲超时、显式关闭、平台更新 | 重建会话,从外部保存的进度与登录状态恢复。 |
| 目标站返回 403 或挑战页 | 站点机器人策略和真实返回内容 | 取得网站支持的访问方式;不能靠改 User-Agent 保证解决。 |
/crawl 无内容 | robots、Content Signals、发现来源和逐页状态 | 区分 disallowed、skipped、errored,调整有依据的任务参数。 |
| 费用高于任务执行时长 | 未关闭的实例、人工等待与 keep_alive | 独占任务完成即关闭,检查 browser-hours 与每日峰值并发。 |
这些检查分别对应平台、页面和业务状态。重试之前先确定失败发生在哪一层,尤其要避免重复提交已经成功的表单或订单。
上线前按真实任务验收
先选一条完整业务路径,例如“打开页面、登录、查询、填写、人工确认、保存结果”,再检查下列结果:
| 验收项 | 操作 | 通过标准 |
|---|---|---|
| 网站可达 | 用实际账户和目标域名运行 | 能区分网站拒绝、认证失败、页面未就绪和服务限额。 |
| 等待逻辑 | 模拟较慢页面和动态加载 | 依据页面业务状态继续,不因固定等待结束而误判完成。 |
| 人工交接 | 分别选择 Done、Failed,并触发超时 | Agent 按结果进入对应分支,失败时不会继续执行后续操作。 |
| 会话恢复 | 主动结束会话后重连任务 | 能识别失效、重建会话并恢复可恢复的进度。 |
| 数据隔离 | 用两个用户的独立状态运行 | Cookie、登录状态、观看入口和产物不会串用。 |
| 容量与费用 | 增加并发和单会话标签页数量 | 不超过账户限额,能观察内存相关失败和实际用量。 |
任务只涉及网页时,Browser Run 能减少浏览器基础设施的维护;需要完整桌面或原生工具时,应使用 Containers/Sandboxes。需要同时操作代码、文件和网页的 Agent,也可以组合 Computer Workspace 与 Browser Run,分别负责长期工作文件和浏览器交互。