跳转到内容
搜索文档

/crawl - 爬取 Web 内容

最后更新 查看 MarkdownAgent 设置

/crawl 端点从起始 URL 抓取内容并跟踪网站链接,最高可配置深度或页面限制。响应可以 HTML、Markdown 或 JSON 格式返回。

/crawl 端点通过 REST API 提供。创建自定义 API Token,并授予 Browser Rendering - Edit 权限。

端点

https://api.cloudflare.com/client/v4/accounts/<account_id>/browser-rendering/crawl

必填字段

  • url(字符串)

其他自定义选项请参阅可选参数

常见使用场景

  • 使用最新 Web 内容构建知识库或训练 AI 系统(如 RAG 应用
  • 跨多个页面抓取和分析内容以进行研究、摘要或监控

工作原理

使用 ``/crawl` 端点分两步:

  1. 启动爬取任务 — 发送 POST 请求启动爬取并收到包含任务 id 的响应。
  2. 请求爬取任务结果 — 发送 GET 请求查询爬取状态或结果。

爬取任务最长运行时间为七天。如果任务未在此时间内完成,将因超时被取消。任务结果在任务完成后可用 14 天,之后任务数据被删除。

启动爬取任务

发送带有 urlPOST 请求以启动爬取任务。API 立即响应并返回 job id,你将使用它检索结果。其他自定义选项请参阅可选参数

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl' \
  -H 'Authorization: Bearer <apiToken>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://developers.cloudflare.com/workers/"
  }'

响应示例:

{
	"success": true,
	"result": "c7f8s2d9-a8e7-4b6e-8e4d-3d4a1b2c3f4e"
}

请求爬取任务结果

要检查爬取任务状态或请求结果,请使用收到的 job id

curl -X GET 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl/c7f8s2d9-a8e7-4b6e-8e4d-3d4a1b2c3f4e' \
  -H 'Authorization: Bearer YOUR_API_TOKEN'

响应包含 status 字段,指示爬取任务的当前状态。可能的任务状态有:

  • running — 爬取任务正在进行中。
  • cancelled_due_to_timeout — 爬取任务超过七天最大运行时间。
  • cancelled_due_to_limits — 爬取任务因达到账户限制而被取消。
  • cancelled_by_user — 爬取任务被用户手动取消。
  • errored — 爬取任务遇到错误。
  • completed — 爬取任务成功完成。

轮询等待完成

由于爬取任务异步运行,你可以定期轮询端点以检查任务何时完成。在请求 URL 中添加 ?limit=1 以保持响应轻量——你只需要 job status,而非完整的爬取记录。

async function waitForCrawl(accountId, jobId, apiToken) {
	const maxAttempts = 60;
	const delayMs = 5000;

	for (let i = 0; i < maxAttempts; i++) {
		const response = await fetch(
			`https://api.cloudflare.com/client/v4/accounts/${accountId}/browser-rendering/crawl/${jobId}?limit=1`,
			{
				headers: {
					Authorization: `Bearer ${apiToken}`,
				},
			},
		);

		const data = await response.json();
		const status = data.result.status;

		if (status !== "running") {
			return data.result;
		}

		await new Promise((resolve) => setTimeout(resolve, delayMs));
	}

	throw new Error("Crawl job did not complete within timeout");
}

任务达到终态后,在不带 limit 参数的情况下获取完整结果。你还可以使用以下查询参数过滤和分页结果:

  • cursor — 分页游标。如果响应超过 10 MB,将包含 cursor 值。将其作为查询参数传递以获取下一页结果。
  • limit — 返回的最大记录数。
  • status — 按 URL 状态过滤:queuedcompleteddisallowedskippederroredcancelled

带查询参数的示例:

curl -X GET 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl/c7f8s2d9-a8e7-4b6e-8e4d-3d4a1b2c3f4e?cursor=10&limit=10&status=completed' \
  -H 'Authorization: Bearer YOUR_API_TOKEN'

响应示例:

{
	"result": {
		"id": "c7f8s2d9-a8e7-4b6e-8e4d-3d4a1b2c3f4e",
		"status": "completed",
		"browserSecondsUsed": 134.7,
		"total": 50,
		"finished": 50,
		"records": [
			{
				"url": "https://developers.cloudflare.com/workers/",
				"status": "completed",
				"markdown": "# Cloudflare Workers\nBuild and deploy serverless applications...",
				"metadata": {
					"status": 200,
					"title": "Cloudflare Workers · Cloudflare Workers docs",
					"url": "https://developers.cloudflare.com/workers/"
				}
			},
			{
				"url": "https://developers.cloudflare.com/workers/get-started/quickstarts/",
				"status": "completed",
				"markdown": "## Quickstarts\nGet up and running with a simple Hello World...",
				"metadata": {
					"status": 200,
					"title": "Quickstarts · Cloudflare Workers docs",
					"url": "https://developers.cloudflare.com/workers/get-started/quickstarts/"
				}
			}
			// ... 48 more entries omitted for brevity
		],
		"cursor": 10
	},
	"success": true
}

出错和被阻止的页面

如果爬取的页面返回 HTTP 错误(如 402403500),该 URL 的记录将具有 "status": "errored"

此信息仅在爬取结果(步骤 2)中可用——启动响应 仅返回 job id。由于爬取任务异步运行,爬虫在启动时不会获取页面内容。

要仅查看出错记录,按 status=errored 过滤:

curl -X GET 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl/{job_id}?status=errored' \
  -H 'Authorization: Bearer YOUR_API_TOKEN'

记录的 status 字段包含源服务器返回的 HTTP 状态码,html 包含响应体。这有助于理解网站所有者在阻止爬虫时的意图——例如,使用 AI Crawl Control 的网站可能返回自定义状态码和消息。

取消爬取任务

要取消正在进行的爬取任务,请使用收到的 job id

curl -X DELETE 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl/c7f8s2d9-a8e7-4b6e-8e4d-3d4a1b2c3f4e' \
  -H 'Authorization: Bearer YOUR_API_TOKEN'

成功取消将返回 200 OK 状态码。任务状态将更新为 cancelled,所有已排队待爬取的 URL 将被取消。

可选参数

除必填的 url 参数外,以下可选参数可用于爬取请求。这些是 ``/crawl` 端点特有的参数。

rendertrue(默认)时,爬取任务还支持所有标准 Browser Run 参数,如 rejectResourceTypesrejectRequestPatterncookiessetExtraHTTPHeaders。当 renderfalse 时,仅支持下表中列出的爬取特定参数。完整列表请参阅 API 参考

可选参数 类型 描述
limit 数字 要爬取的最大页面数(默认 10,最大 100,000)。
depth 数字 从起始 URL 爬取的最大链接深度(默认 100,000,最大 100,000)。
source 字符串 用于发现 URL 的来源。选项为 allsitemapslinks。默认为 all
formats 字符串数组 响应格式(默认为 HTML,其他选项为 Markdown 和 JSON)。JSON 格式默认利用 Workers AI 进行数据提取,这会在 Workers AI 上产生用量。请参阅 /json 端点 了解更多,包括如何使用自定义模型和 fallback。
render 布尔值 如果为 false,执行快速 HTML 获取而不执行 JavaScript(默认为 true,了解 render 更多信息)。
jsonOptions 对象 仅当 formats 包含 json 时需要。包含 promptresponse_formatcustom_ai 属性(类型与 /json 端点 相同)。
maxAge 数字 爬虫可以使用缓存资源的最大时间(秒),超过此时间必须从源服务器重新获取(默认 86,400,最大 604,800)。仅当 URL 和参数完全匹配时,缓存才从 R2 提供。
modifiedSince 数字 Unix 时间戳(秒),表示仅爬取自此时间以来修改的页面。
options.includeExternalLinks 布尔值 如果为 true,跟踪到外部域的链接(默认为 false)。
options.includeSubdomains 布尔值 如果为 true,跟踪起始 URL 子域的链接(默认为 false)。
options.includePatterns 字符串数组 仅访问匹配其中一个通配符模式的 URL。使用 * 匹配除 / 外的任意字符,或使用 ** 匹配包括 / 在内的任意字符。
options.excludePatterns 字符串数组 不访问匹配任何这些通配符模式的 URL。使用 * 匹配除 / 外的任意字符,或使用 ** 匹配包括 / 在内的任意字符。
crawlPurposes 字符串数组 声明爬取内容的预期用途,用于 Content Signals 强制执行。允许值:searchai-inputai-train。默认为 ["search", "ai-input", "ai-train"]。如果目标站点的 robots.txt 包含将你声明的任何用途设置为 noContent-Signal 指令,爬取请求将被拒绝并返回 400 错误。请参阅 Content Signals 了解详情。

模式行为

excludePatterns 具有严格更高的优先级。如果 URL 匹配排除规则,则跳过,无论是否匹配包含规则。

  • 无规则 — 索引所有内容。
  • 仅排除 — 索引除匹配排除模式项之外的所有内容。
  • 仅包含 — 仅索引匹配包含模式的项;忽略其他所有内容。

查看跳过的 URL

要查看已发现但被跳过的 URL,使用 status=skipped 查询爬取任务结果。URL 可能因 includeExternalLinksincludeSubdomainsincludePatterns/excludePatternsmodifiedSince 参数而被跳过。跳过的 URL 也将在未来版本的仪表板中可见。

curl -X GET 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl/{job_id}?status=skipped' \
  -H 'Authorization: Bearer YOUR_API_TOKEN'

render 参数

如果使用 render: true(默认),crawl 端点会启动无头浏览器并执行页面 JavaScript。如果使用 render: falsecrawl 端点会快速获取 HTML 而不执行 JavaScript。

当页面在浏览器中构建内容时使用 render: true。当所需内容已在初始 HTML 响应中时使用 render: false

使用 render: true 的爬取使用无头浏览器,按常规 Browser Run 定价计费。使用 render: false 的爬取在 Workers 上运行而非无头浏览器。Beta 期间,render: false 爬取不计费。Beta 结束后,将按 Workers 定价 计费。

包含所有可选参数的示例

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl' \
  -H 'Authorization: Bearer <apiToken>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://www.exampledocs.com/docs/",
    "crawlPurposes": ["search"],
    "limit": 50,
    "depth": 2,
    "formats": ["markdown"],
    "render": false,
    "maxAge": 7200,
    "modifiedSince": 1704067200,
    "source": "all",
    "options": {
      "includeExternalLinks": true,
      "includeSubdomains": true,
      "includePatterns": [
        "**/api/v1/*"
      ],
      "excludePatterns": [
        "*/learning-paths/*"
      ]
    }
}'

高级用法

文档站点爬取

仅爬取文档页面并排除特定部分:

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl' \
  -H 'Authorization: Bearer <apiToken>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://example.com/docs",
    "limit": 200,
    "depth": 5,
    "formats": ["markdown"],
    "options": {
      "includePatterns": [
        "https://example.com/docs/**"
      ],
      "excludePatterns": [
        "https://example.com/docs/changelog/**",
        "https://example.com/docs/archive/**"
      ]
    }
  }'

使用 AI 提取产品目录

使用 json 格式提取结构化产品数据。默认利用 Workers AI。更多信息请参阅 /json 端点

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl' \
  -H 'Authorization: Bearer <apiToken>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://shop.example.com/products",
    "limit": 50,
    "formats": ["json"],
    "jsonOptions": {
      "prompt": "Extract product name, price, description, and availability",
      "response_format": {
        "type": "json_schema",
        "json_schema": {
          "name": "product",
          "properties": {
            "name": "string",
            "price": "number",
            "currency": "string",
            "description": "string",
            "inStock": "boolean"
          }
        }
      }
    },
    "options": {
      "includePatterns": [
        "https://shop.example.com/products/*"
      ]
    }
  }'

快速静态内容获取

获取静态 HTML 而不渲染,以更快爬取静态站点:

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl' \
  -H 'Authorization: Bearer <apiToken>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://example.com",
    "limit": 100,
    "render": false,
    "formats": ["html", "markdown"]
  }'

带身份验证的爬取

爬取 HTTP 身份验证后或带有自定义请求头的页面:

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl' \
  -H 'Authorization: Bearer <apiToken>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://secure.example.com",
    "limit": 50,
    "authenticate": {
      "username": "user",
      "password": "pass"
    }
  }'

你也可以使用 cookies 或自定义请求头进行基于 token 的身份验证:

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl' \
  -H 'Authorization: Bearer <apiToken>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://api.example.com/docs",
    "limit": 100,
    "setExtraHTTPHeaders": {
      "X-API-Key": "your-api-key"
    }
  }'

等待动态内容

爬取动态加载内容的单页应用:

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl' \
  -H 'Authorization: Bearer <apiToken>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://app.example.com",
    "limit": 50,
    "gotoOptions": {
      "waitUntil": "networkidle2",
      "timeout": 60000
    },
    "waitForSelector": {
      "selector": "[data-content-loaded]",
      "timeout": 30000,
      "visible": true
    }
  }'

阻止不必要的资源

通过阻止图片和媒体加快爬取。rejectResourceTypes 仅在 rendertrue(默认)时可用。

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl' \
  -H 'Authorization: Bearer <apiToken>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://example.com",
    "limit": 100,
    "rejectResourceTypes": [
      "image",
      "media",
      "font",
      "stylesheet"
    ]
  }'

爬虫行为

爬虫如何发现 URL

爬虫按以下顺序发现和处理 URL(使用 source: all 时,即默认):

  1. 起始 URL — 请求中指定的 URL。
  2. Sitemap 链接 — 在网站 sitemap 中找到的 URL。
  3. 页面链接 — 从页面抓取的链接(如果 sitemap 中尚未找到)。

使用 source 参数自定义爬虫使用的来源。可用选项有:

  • all — 同时使用 sitemap 和页面链接(默认)。
  • sitemaps — 仅爬取网站 sitemap 中找到的 URL。
  • links — 仅爬取页面上找到的链接,忽略 sitemap。

robots.txt 和 bot 防护

/crawl 端点遵循 robots.txt 文件的指令,包括 crawl-delay。如果站点未在 robots.txt 中指定 crawl-delay,爬虫对同一域名的请求之间使用 0.5 秒的默认延迟,以避免压垮源服务器。所有 /crawl 被指示不爬取的 URL 在响应中列出,状态为 "disallowed"。有关为计划爬取的站点配置 robots.txt 和 sitemap 的指导,请参阅 robots.txt 和 sitemap。如果你想阻止 /crawl 端点访问你的网站,请参阅使用 robots.txt 阻止爬虫

User-Agent

/crawl 端点使用 CloudflareBrowserRenderingCrawler/1.0 作为 User-Agent,与其他 Quick Actions 端点不同。此 User-Agent 不可自定义。与其他 Quick Actions 端点不同,/crawl 端点不支持 userAgent 参数。

默认 User-Agent 字符串的完整列表请参阅自动请求头

Content Signals(内容信号)

/crawl 端点遵循目标站点 robots.txt 文件中找到的 Content Signals 指令。Content Signals 是站点所有者表达其内容如何被自动化系统使用偏好的一种方式。更多背景请参阅通过 Cloudflare 新的 Content Signals Policy 为用户提供选择

站点所有者可以在 robots.txt 中包含 Content-Signal 指令,以允许或禁止特定类别的使用:

  • search — 构建搜索索引并提供带有链接和摘要的搜索结果。
  • ai-input — 在查询时将内容输入 AI 模型(例如检索增强生成或 grounding)。
  • ai-train — 训练或微调 AI 模型。

例如,允许搜索索引但禁止 AI 训练的 robots.txt

robots.txttxt
User-Agent: *
Content-Signal: search=yes, ai-train=no
Allow: /

/crawl 如何强制执行 Content Signals

默认情况下,/crawl 声明所有三种用途:["search", "ai-input", "ai-train"]。如果目标站点将任何这些内容信号设置为 no,除非你使用 crawlPurposes 参数显式缩小声明的用途以排除不允许的使用,否则爬取请求将在启动时被拒绝并返回 400 Bad Request 错误。

这意味着:

  1. 站点没有 Content Signals — 爬取正常进行。
  2. 站点有 Content Signals,且你声明的所有用途均被允许 — 爬取正常进行。
  3. 站点将内容信号设置为 no,且该用途在你的 crawlPurposes — 爬取请求被拒绝,返回 400 错误,消息为 Crawl purpose(s) completely disallowed by Content-Signal directive

要爬取禁止 AI 训练但允许搜索的站点,将 crawlPurposes 设置为仅你需要的用途:

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl' \
  -H 'Authorization: Bearer <apiToken>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://example.com",
    "crawlPurposes": ["search"],
    "formats": ["markdown"]
  }'

在此示例中,由于操作者仅将 search 声明为用途,即使站点设置 ai-train=no,爬取也会成功。

故障排除

爬取任务无结果或所有 URL 被跳过

如果爬取任务完成但返回空的 records 数组,或所有 URL 显示 skippeddisallowed 状态:

  • robots.txt 阻止 — 爬虫遵循 robots.txt 规则。/crawl 端点标识自身为 CloudflareBrowserRenderingCrawler/1.0。检查目标站点的 robots.txt 文件以验证是否允许此 user agent。被阻止的 URL 显示为 "status": "disallowed"
  • 模式过滤器过于严格 — 你的 includePatterns 可能不匹配站点上的任何 URL。先尝试不使用模式爬取以确认 URL 可被发现,然后添加模式。
  • 未找到链接 — 起始 URL 可能不包含链接。尝试使用 source: "sitemaps"、增大 depth 参数,或将 includeSubdomainsincludeExternalLinks 设置为 true

爬取被 Content Signals 拒绝

如果爬取请求返回 400 Bad Request,消息为 Crawl purpose(s) completely disallowed by Content-Signal directive,则目标站点的 robots.txt 包含禁止你声明的一个或多个 crawlPurposesContent-Signal 指令。要解决此问题,检查站点的 robots.txt 中的 Content-Signal: 条目,并将 crawlPurposes 设置为仅你需要的用途。例如,如果站点设置 ai-train=no 而你只需要搜索索引,使用 "crawlPurposes": ["search"]。请参阅 Content Signals 了解详情。

爬取任务耗时过长

如果爬取任务长时间保持 running 状态:

  • 页面加载缓慢 — 具有重度 JavaScript 的页面渲染时间更长。如果你需要的内容在初始 HTML 中,请使用 render: false
  • 速率限制 — 爬虫强制执行每域速率限制,以避免压垮源服务器。如果站点在 robots.txt 中指定了 crawl-delay,爬虫会遵循它。否则,爬虫对同一域名的请求之间使用 0.5 秒的默认延迟。如果你运行多个针对同一域名的爬取任务,它们共享相同的每域速率限制,这可能导致所有任务比单独运行耗时更长。
  • 不必要的资源 — 使用 rejectResourceTypes 阻止内容提取不需要的资源(例如 imagemediafont)。

爬取任务因限制被取消

cancelled_due_to_limits 状态表示你的账户达到了浏览器时间限制。Workers Free 套餐 账户每天浏览器使用时间上限为 10 分钟。要解决此问题:

  • 升级到 Workers Paid 套餐 以获得更高的限制
  • 对静态内容使用 render: false 以避免消耗浏览器时间。
  • 增大 maxAge 以尽可能使用缓存结果。
  • 减小 limit 参数。

JSON 提取错误

如果 json 格式返回 null 或空结果:

  • 提供清晰的 prompt — 具体说明要提取什么数据以及它在页面上的位置(例如,「从主要产品部分提取产品名称、价格和描述」)。
  • 定义响应 schema — 使用带有 JSON schema 的 response_format 以强制预期的输出结构。
  • 使用自定义模型 — 如果默认 Workers AI 模型未产生预期结果,使用 custom_ai 参数指定不同模型。请参阅使用自定义模型(BYO API Key) 了解详情。

如有疑问或遇到其他错误,请参阅 Browser Run 常见问题与故障排除指南

故障排除

如有疑问或遇到错误,请参阅 Browser Run 常见问题与故障排除指南

这篇文档对您有帮助吗?