跳到正文
高级工具5 credits

scrape_with_actions

执行包括点击、滚动、输入和表单自动填充在内的浏览器操作链,并支持截图捕获。非常适合登录流程、无限滚动、模态对话框以及复杂的重 JavaScript 网站。

使用场景

登录流程

自动化登录表单,访问登录墙后的已认证内容

无限滚动

从社交媒体动态流和产品列表等无限滚动页面抓取内容

模态对话框

与弹窗、模态框和动态浮层进行交互

重 JavaScript 网站

处理 SPA 以及通过 AJAX 动态加载内容的网站

多步骤表单

在多步骤向导和复杂表单提交中进行导航

可视化测试

在每一步捕获截图,用于调试和视觉回归测试

Endpoint

POST/api/v1/tools/scrape_with_actions
Auth Required
Free 计划 1 req/s
5 credits

Parameters

NameTypeRequiredDefaultDescription
url
stringRequired-
在运行操作链之前要加载的 URL
Example: https://app.example.com/dashboard
actions
arrayRequired-
在抓取之前要运行的 1-20 个浏览器操作的有序列表。每个元素都是一个对象,其 `type` 为 `wait`、`click`、`type`、`press`、`scroll`、`screenshot`、`executeJavaScript`、`select`、`hover`、`navigate` 或 `snapshot`,外加与类型相关的字段:`selector`(CSS 目标,或来自先前 `snapshot` 的 `@e1` 引用)、`text`(用于 `type`)、`key`(用于 `press`)、`script`(用于 `executeJavaScript`)、`duration`/`condition`(用于 `wait`)、`button`/`clickCount`/`delay`(用于 `click`)、`direction`/`distance`/`toElement`(用于 `scroll`)、`fullPage`/`quality`/`format`(用于 `screenshot`)、`value` 或 `values`(用于 `select`)、`url`/`waitUntil`(用于 `navigate`)以及 `interactiveOnly`/`maxNodes`(用于 `snapshot`)。`select` 接受单个 `value` 或 `values` 数组,普通字符串会按选项的 value 或可见文本进行匹配;`hover` 需要 `selector`,并可选 `force` 和 `position`。`snapshot` 会为页面上的每个可交互元素(包括开放 shadow root 和 iframe 内的元素)附上稳定的引用(按文档顺序为 `@e1`、`@e2`、…),同一条链中后续的任何操作都可以用这些引用代替 CSS 选择器作为目标;导航会使引用失效,因此页面变化后需重新执行 `snapshot`。任何操作均可选:`timeout`(每个操作,默认 10000ms,区别于按整条链计算预算的 `browserOptions.timeout`)、`description`、`continueOnError`(默认 false)、`retries`(0-5,默认 1)和 `captureAfter`(默认 false)。
Example: [{"type": "click", "selector": "#login"}, {"type": "type", "selector": "#email", "text": "user@example.com"}, {"type": "wait", "duration": 1000}, {"type": "screenshot"}]
formats
arrayOptional["json"]
要返回的输出格式:`markdown`、`html`、`json` 或 `text`。需要图像时,请在希望截图的位置添加一个 `{"type": "screenshot"}` 操作。
Example: ["markdown"]
captureIntermediateStates
booleanOptionalfalse
在每个操作之后捕获页面状态:`intermediateStates[]` 中每个操作对应一项(`capturePoint` 是该操作从 1 开始计的位置),包含当时的 `url`、`title` 和所请求的格式
Example: true
formAutoFill
objectOptional-
一步填写并提交表单。结构:`{ fields: [{ selector, value, type: text|select|checkbox|radio|file, waitAfter }], submitSelector, waitAfterSubmit }`——`waitAfterSubmit` 默认为 2000ms。每个字段的 `type` 决定填写方式:`text`(默认)输入该值,`select` 按值或标签选择选项,`checkbox` 和 `radio` 勾选该控件——若选择器匹配整组控件(例如 `input[name=size]`),则勾选 `value` 属性等于 `value` 的那一个;值为 `"false"` 的 checkbox 会被取消勾选。不支持 `file`,该动作会失败。
Example: {"fields": [{"selector": "#email", "value": "user@example.com", "type": "text"}], "submitSelector": "#login"}
browserOptions
objectOptional-
浏览器配置:`headless`(默认 true)、`userAgent`、`viewportWidth`(默认 1280,范围 800-1920)、`viewportHeight`(默认 720,范围 600-1080)、`timeout`(默认 30000ms,范围 10000-120000)以及 `stealth`(默认 false)。请将 `timeout` 保持在约 25 秒的 REST 窗口内。将 `stealth` 设为 true,可用隐身 Chromium 引擎的 `medium` 配置运行整条操作链,而不使用标准浏览器池——该布尔值是唯一的开关,级别、指纹随机化和引擎选择都无法在此设置。它启动更慢,并且只是渲染 JavaScript,并不解决挑战。`consent`(默认 `"off"`)处理 cookie 和同意横幅:`"reject"` 会在初始导航之后以及每个 `navigate` 操作之后各对横幅执行一次 DuckDuckGo autoconsent 的拒绝(opt-out),上限 2 秒;`"accept"` 则改为同意。当它不是 `"off"` 时,结果会带有初始导航的 `consent: { cmp, action, ms }`,每个 `navigate` 操作的结果也会带有各自的 `result.consent`。`cmp` 是匹配到的同意管理平台,没有匹配时为 `null`;`action` 为 `optOut`、`optIn`、`hide`(外观规则隐藏了横幅)、`timeout`(检测到横幅,但未在 2 秒上限内完成应答)、`error` 或 `none`(没有匹配);`ms` 是耗时。操作链绝不会因为没有匹配到平台而失败。默认值为 off,这样自行点击横幅的操作链仍能照常工作。`proxyRotation` 让隐身浏览器经由你自备的代理访问:`{ enabled, proxies, rotationInterval }`,其中 `enabled` 默认 false,`rotationInterval`(默认 300000)是在一个代理上停留的最短毫秒数,之后列表才切换到下一个。它要求 `stealth: true`,否则会被拒绝。代理仅在 Chromium 引擎上按上下文生效;Camoufox 会拒绝单次调用的 `proxyRotation`,因为它在启动浏览器时就应用代理,并在多次调用之间共享该浏览器。`proxies` 中的每一项都是代理 URL——`"http://user:pass@host:port"`(密码中含 `@`、`:` 或 `/` 时请做百分号编码),或用于无需认证的 HTTP 代理的裸 `"host:port"`;支持 `http`、`https`、`socks4` 和 `socks5`。位于回环、私有、链路本地或云元数据地址上的代理会被拒绝,凭据也绝不会回显——结果中的 `metadata.browserOptions` 会将其脱敏显示。CrawlForge 不提供代理:托管的隐身浏览器从数据中心地址发出请求,而 IP 信誉封锁是任何指纹都解决不了的,能通过它的是住宅代理。
Example: {"viewportWidth": 1440, "viewportHeight": 900, "timeout": 20000}
extractionOptions
objectOptional-
内容提取选项:`selectors`(要提取数据的 CSS 键→值映射)、`includeMetadata`(默认 true)、`includeLinks`(默认 true)和 `includeImages`(默认 true)。
Example: {"selectors": {"title": "h1", "price": ".price"}}
continueOnActionError
booleanOptionalfalse
当某个操作失败时继续执行其余操作,而不是中止整个操作链
Example: false
maxRetries
numberOptional0
失败时整条操作链的重试次数(0-3)。每次重试都会重新导航到起始 URL 并重放所有操作,因此每次重试的开销与首次运行相同;每次尝试都会记录在 `attempts[]` 中
Example: 0
screenshotOnError
booleanOptionaltrue
发生错误时捕获截图
Example: true
respect_robots
booleanOptionaltrue
遵守目标站点的 robots.txt。省略该参数时按合规默认值(`true`)执行:robots.txt 对 `CrawlForge` 禁止的 URL 会在打开浏览器之前被拒绝,此端点不会为此扣费,每个 `navigate` 操作也会同样检查。页面最终停在哪里也会再次检查——无论是经过重定向、点击还是表单提交——一旦落到被禁止的路径,调用即失败,且不会返回该页面的任何内容。无论此参数如何设置,都会遵守站点的 `Crawl-delay`:`navigate`,以及可能让页面跳转的 `click`、`press`、`select` 或 `check`,都会在距上次请求该页面所在主机满这段时间后才执行。仅在您与目标站点另有约定时才设为 `false`——该覆盖会记录到您的 API key 上。
Example: true
max_inline_chars
numberOptional40000
内联返回的最大结果大小,以其 JSON 的字符数计(1,000-10,000,000)。超过后,响应会携带 `preview`(结果主文本字段的前 `max_inline_chars` 个字符)、`result_handle`、`total_chars`、`truncated: true` 和 `expires_at`,其余部分由 [read_result](/docs/api-reference/tools/read-result) 读取,每次调用 1 credit。已存储的结果保留 1 小时。
Example: 40000
redact_pii
boolean | objectOptionalfalse
在结果被存储或返回之前,从本次调用返回的文本中移除个人数据。 `true` 是 `{ mode: "fast" }` 的简写:四个正则类别全开,以标签替换。只要请求了脱敏,响应就会在 `data` 内带上 `redaction: { entities, count, mode }`,即使没有任何匹配(`count: 0`)也会带上,因此“什么都没找到”永远不会被误认为“参数被忽略了”;没有命中的类别会被省略,而不是报成 `0`。脱敏在结果存储**之前**执行,因此超出阈值、之后再用 [read_result](/docs/api-reference/tools/read-result) 读回的结果本身就已脱敏。两条刻意的边界:地址类字段(`url`、`link`、`href`、`canonical_url`)从不脱敏;由文本派生的计数(`content_length`、`word_count`、`character_count`)描述的是抽取时的文本,即脱敏之前的文本。
Example: true

可用的操作类型

wait
等待指定的毫秒数
action.jsonJson
{"type": "wait", "duration": 2000}
click
通过 CSS 选择器点击元素
action.jsonJson
{"type": "click", "selector": "#button"}
type
在输入框中输入文本
action.jsonJson
{"type": "type", "selector": "#search", "text": "query"}
press
按下键盘按键
action.jsonJson
{"type": "press", "key": "Enter"}
scroll
滚动到元素或位置
action.jsonJson
{"type": "scroll", "toElement": "#content"}
screenshot
捕获截图
action.jsonJson
{"type": "screenshot"}
executeJavaScript
执行自定义 JavaScript。除非自托管服务器设置了 ALLOW_JAVASCRIPT_EXECUTION=true,否则该操作处于禁用状态;托管 API 会拒绝该操作。
action.jsonJson
{"type": "executeJavaScript", "script": "window.scrollTo(0, 0)"}
select
在 <select> 中选择选项:selector 指定下拉框,然后使用 value(单个选项)或 values(多个选项)。普通字符串会按选项的 value 或可见文本进行匹配。
hover
将指针悬停在 selector 指定的元素上——适用于仅在悬停时出现的菜单和提示。force 与 position 的行为与 click 相同。
navigate
在同一浏览器会话中加载另一个 url,因此先前操作留下的 cookie、localStorage 和登录状态都会保留。可选的 waitUntil 取值为 load、domcontentloaded(默认)、networkidle 或 commit。新 URL 会经过与初始 URL 相同的 robots.txt 和 SSRF 检查,因此无法借此绕过限制。每次导航都会检查是否遇到机器人墙:该操作的 result 会带有 httpStatus,识别出墙时还会带有 blocked: { vendor, evidence }。操作本身仍然成功——墙只会被报告,不会让操作失败。
snapshot
以缩进的无障碍树列出页面向指针和键盘开放的内容,其中每个可交互元素(包括开放 shadow root 和 iframe 内的元素)都按文档顺序带有稳定的引用:[document] "Example Domain",然后是 @e1 [textbox] "Search..." 和 @e2 [button] "Search"。iframe 或 shadow root 内的元素和其他元素一样获得普通的 @eN 引用。将 interactiveOnly(默认 true)设为 false 会一并列出标题和地标元素,但它们永远不会获得引用;maxNodes(默认 200,最大 1000)限制树中列出的节点数量(在默认设置下,每个节点各对应一个引用),当该上限中断遍历时,结果会报告 truncated: true。此操作在 actionResults 中的条目会以 result.tree 返回该树,同时包含 snapshotId、url、title、refCount、nodeCount、truncated、interactiveOnly 和 source——树来自浏览器原生无障碍快照时为 aria,由后备遍历生成时为 walk。
action.jsonJson
{"type": "snapshot", "interactiveOnly": true, "maxNodes": 200}

通过引用定位元素

每次导航都检查机器人墙

请求示例

terminalBash
# 1. Snapshot the page to learn its interactive elements and their refs.
curl -X POST https://crawlforge.dev/api/v1/tools/scrape_with_actions \
  -H "X-API-Key: cf_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://app.example.com/login",
    "actions": [{"type": "snapshot"}],
    "formats": ["json"]
  }'

# actionResults[0].result.tree comes back as:
#   [document] "Sign in"
#     @e1 [textbox] "Email"
#     @e2 [textbox] "Password"
#     @e3 [button] "Sign in"

# 2. Target those refs instead of guessing selectors. The chain snapshots
#    again first, which stamps the refs onto this fresh load.
curl -X POST https://crawlforge.dev/api/v1/tools/scrape_with_actions \
  -H "X-API-Key: cf_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://app.example.com/login",
    "actions": [
      {"type": "snapshot"},
      {"type": "type", "selector": "@e1", "text": "user@example.com"},
      {"type": "type", "selector": "@e2", "text": "secret123"},
      {"type": "click", "selector": "@e3"},
      {"type": "wait", "duration": 1000},
      {"type": "screenshot"}
    ],
    "formats": ["markdown"]
  }'

响应示例

200 OK9000ms
{
"success": true,
"data": {
"success": true,
"url": "https://app.example.com/login",
"finalUrl": "https://app.example.com/dashboard",
"httpStatus": 200,
"engine": "chromium",
"navigations": [
{
"url": "https://app.example.com/login",
"finalUrl": "https://app.example.com/login",
"httpStatus": 200
},
{
"url": "https://app.example.com/dashboard",
"finalUrl": "https://app.example.com/dashboard",
"httpStatus": 200,
"trigger": "click"
}
],
"actionResults": [
{
"id": "action_1759480001102_k2m8x1q0z",
"type": "click",
"success": true,
"executionTime": 640
},
{
"id": "action_1759480001790_p7c4n9d2a",
"type": "wait",
"success": true,
"executionTime": 1001
},
{
"id": "action_1759480002805_h5t1v8r3e",
"type": "screenshot",
"success": true,
"executionTime": 212,
"result": {
"format": "png",
"fullPage": false,
"resourceUri": "crawlforge://screenshot/action_1759480002805_h5t1v8r3e"
}
}
],
"totalActions": 3,
"successfulActions": 3,
"failedActions": 0,
"actionsExecuted": 3,
"content": {
"markdown": "# Dashboard\n\nWelcome back — you are now signed in..."
},
"screenshots": [
{
"actionId": "action_1759480002805_h5t1v8r3e",
"format": "png",
"fullPage": false,
"timestamp": 1759480002805,
"resourceUri": "crawlforge://screenshot/action_1759480002805_h5t1v8r3e"
}
]
},
"credits_used": 5,
"credits_remaining": 995,
"processing_time": 9000
}
Field Descriptions
data.url你请求的 URL。无论操作链走了多远,它都保持不变
data.finalUrl操作链最终停留的位置,包含任何重定向、点击或表单提交之后的结果
data.httpStatus操作链加载的最后一个主框架文档的状态码
data.navigations按顺序列出的每一次导航,索引 0 为初始加载。由点击或表单提交引起的条目带有 `trigger`,即让页面跳转的操作类型
data.actionResults每个操作一项,包含其 `type`、`success`、耗时以及该操作自身的 `result`
data.actionsExecuted已执行的操作数量;`successfulActions` 和 `failedActions` 是其细分
data.content.markdown所有操作完成后,以每种请求格式返回的页面内容
data.screenshots始终存在:每个 `screenshot` 操作一项,出错时另有一张,没有截图时为空数组。每一项都是 `crawlforge://screenshot/{actionId}` 资源 URI,而不是内联的 base64,并且此 REST 端点会原样传递该 URI 而不解析它——因此目前只能通过 CrawlForge MCP 服务器读取图像数据
credits_used本次请求扣除的 credits(每次抓取 5 个)
processing_time总耗时(毫秒),包含所有操作和等待

错误处理

浏览器运行时未配置(503 TOOL_NOT_AVAILABLE)

该工具需要浏览器自动化运行时。当托管执行后端未配置时,调用会立即返回 503,且不扣除 credits。

执行后端超时(504 MCP_UPSTREAM_TIMEOUT)

导航加上动作链超出了执行后端的时间预算。请缩短等待、减少动作数量,或稍后重试。失败不计费。

被 robots.txt 阻止(502 TOOL_ERROR)

目标站点的 robots.txt 对 CrawlForge 禁止了该 URL,因此没有启动任何浏览器,也没有产生任何费用。每个 navigate 操作都会同样检查,而不仅是初始 URL。页面最终停在哪里也会同样检查:如果重定向、点击或表单提交把页面带到被禁止的路径,错误信息会同时给出两个 URL(“The page moved from … to …”),操作链就此停止,且不产生任何费用。登录页和搜索页常常被禁止,因此经过这类页面的流程需要使用该覆盖。若您与目标站点另有约定,可设置 respect_robots: false 予以覆盖——该覆盖会记录到您的 API key 上。

停在机器人墙上(502 BLOCKED)

操作链最终停留的文档是机器人墙或挑战中间页,因此调用会失败,而不是把墙当作页面返回,且不扣除任何费用。响应体包含指明该墙的 blocked: { vendor, evidence }、操作链的 navigations,以及已知时的最终 httpStatus,便于你看出是哪一次导航遇到了它。工具无法归属到具体厂商的 HTTP 错误页或占位页则以 502 TOOL_ERROR 失败,同样不扣除费用。较早导航中遇到的墙不会导致调用失败,而是在 navigations 中报告。该工具只报告墙,不会破解它;如果封锁针对的是网络地址,请通过 browserOptions.proxyRotation 让操作链经由你自己的代理。

无效操作(400 Bad Request)

一个或多个操作的参数无效。请检查操作类型和必填字段。

Credits 不足(402 Payment Required)

您的账户 credits 不足(需要 5 个)。购买更多 credits 或 升级您的套餐。

超出速率限制(429 Too Many Requests)

您已超出套餐的速率限制。请稍候片刻,或 升级您的套餐 以获得更高限额。

Credit 费用

5 credits
每次请求 5 credits
每次成功的 scrape_with_actions 请求消耗 5 credits,与操作数量无关。

Free 套餐: 1,000 个一次性试用 credits = 200 条操作链

Hobby 套餐: 5,000 credits/月 = 1,000 条操作链($19/mo)

Professional 套餐: 100,000 credits/月 = 20,000 条操作链($99/mo)

Business 套餐: 500,000 credits/月 = 100,000 条操作链($399/mo)

相关工具