快速摘要: 2026 年 3 月 10 日,Cloudflare 在其 Browser Rendering 服务中正式上线了 /crawl 端点(Open Beta)。开发者只需发送一个 POST 请求,就能异步爬取整个网站,并将内容以 HTML、Markdown 或结构化 JSON 的格式返回。 该端点默认遵守目标网站的 robots.txt 和 AI Crawl Control 规则,自我标识为机器人,不会绕过反爬保护。对于 RAG 应用构建、知识库搭建、文档站内容采集等场景,这是一个极具吸引力的基础设施级方案。往下看,莫潇羽@无忆研习社 将从技术原理、API 参数细节、实操步骤、定价策略、竞品对比等多个维度,为你做一次彻底的拆解。
一、为什么这件事值得关注
如果你是一个做过数据采集工作的开发者,你一定对这套流程不陌生:先选一个爬虫框架(Scrapy、Puppeteer、Playwright),然后搭建无头浏览器环境,处理 JavaScript 渲染问题,编写分页逻辑,管理代理池,还得时刻应对目标网站的反爬策略升级。整套流程下来,光是基础设施的搭建和运维就要消耗大量的时间和精力。
而 Cloudflare 这次发布的 /crawl 端点,本质上是把上面这一整套工作压缩成了两个 HTTP 请求——一个 POST 发起任务,一个 GET 获取结果。不需要你自己管理浏览器实例,不需要处理链接发现逻辑,不需要编写 sitemap 解析代码,所有这些都由 Cloudflare 的全球边缘网络在后台完成。
这件事之所以引发广泛讨论,还有一个颇具戏剧性的原因:Cloudflare 本身是全球最大的网站防护服务商之一,它的核心业务之一就是帮助网站抵御恶意爬虫和 DDoS 攻击。现在,这家以"反爬"闻名的公司,亲手推出了一款功能强大的爬虫工具。用社区里流传最广的一句话来形容——"以前收费帮你挡爬虫,现在收费帮你爬别人。"
当然,事情并不是这么简单。Cloudflare 官方在回应中也给出了自己的解释:合规爬虫的开发成本很高,很多开发者以此为借口不做合规处理,导致大量野蛮爬虫横行。与其继续玩猫鼠游戏,不如把"做正确的事"变得更简单——默认遵守 robots.txt,使用合规的 User-Agent,不超载目标服务器。这个逻辑在当前 AI 数据需求井喷的背景下,是说得通的。
莫潇羽@无忆研习社 认为,不管你对这个商业策略怎么看,从技术角度来说,这个工具的实用价值是实实在在的。下面我们就来深入了解它的工作原理和使用方法。
二、/crawl 端点的技术原理:它到底是怎么工作的
要理解 /crawl 端点,首先需要了解它背后的基础设施——Cloudflare Browser Rendering。
2.1 Browser Rendering 是什么
Cloudflare Browser Rendering 是 Cloudflare 提供的一项托管服务,允许开发者通过 API 调用来操控运行在 Cloudflare 全球边缘网络上的无头 Chrome 浏览器实例。你可以把它理解为一个"云端浏览器集群",部署在 Cloudflare 遍布全球的数据中心里。
传统方案中,你需要自己在服务器上安装 Chrome 或 Chromium,再通过 Puppeteer 或 Playwright 来驱动它。而 Browser Rendering 把这层基础设施全部托管了——你只需要发送 HTTP 请求,Cloudflare 就会在离目标网站最近的边缘节点上启动一个浏览器实例来完成任务。
Browser Rendering 的底层运行在 Cloudflare 的全球边缘计算网络之上。截至 2026 年,Cloudflare 在全球拥有超过 300 个数据中心,覆盖六大洲的主要城市和互联网交换中心。这意味着当你发起一个爬取请求时,浏览器实例会被分配到离目标网站服务器物理距离最近的数据中心上运行。这种架构带来了两个显著的好处:一是网络延迟更低,页面加载更快,浏览器时间消耗更少;二是天然的地理分布避免了从单一 IP 地址发起大量请求的风险,降低了被目标网站误判为恶意爬虫的概率。
从技术实现来看,每个 Browser Rendering 实例本质上是一个运行在 Cloudflare 边缘服务器上的无头 Chromium 浏览器进程。Cloudflare 维护了一个全球化的浏览器实例池,当你的请求到达时,系统会从池中分配一个空闲实例(或者创建一个新实例),执行完任务后回收。浏览器实例默认在 60 秒不活动后自动关闭,你也可以通过 keep_alive 选项将这个不活动超时时间延长到最多 10 分钟。
对于开发者来说,你完全不需要关心这些底层细节。从你的视角来看,你只是在调用一个 REST API,所有的浏览器管理、实例调度、资源回收都由 Cloudflare 在后台完成。
2.2 /crawl 的两种渲染模式
/crawl 端点提供了两种截然不同的工作模式,理解它们的区别对于控制成本和性能至关重要:
模式一:render: true(默认模式)
这是完整的浏览器渲染模式。当你启动一个 crawl 任务且 render 参数为 true(默认值)时,Cloudflare 会为每个被爬取的页面启动一个真实的无头 Chrome 实例。浏览器会完整执行页面上的 JavaScript 代码,等待 AJAX 请求完成,所有动态内容加载完毕后,再捕获最终的 DOM 状态。
这种模式的优势在于它能够处理现代的单页应用(SPA),比如用 React、Vue、Angular 构建的网站。这类网站的内容往往不在初始 HTML 中,而是通过 JavaScript 动态加载的。如果你直接请求这类网站的 HTML,拿到的很可能只是一个空壳。render: true 模式解决的就是这个问题。
代价是:每个页面都需要消耗浏览器运行时间,这个时间会计入你的 Browser Rendering 用量配额。
模式二:render: false(静态模式)
这种模式完全不启动浏览器。Cloudflare 直接通过 Workers 发起一个普通的 HTTP 请求来获取目标页面的原始 HTML。没有 JavaScript 执行,没有 DOM 渲染,拿到的就是服务器返回的原始内容。
这种模式的速度非常快,成本也极低。在当前 Beta 期间,render: false 模式甚至是完全免费的,正式版之后才会按照 Workers 标准定价计费。对于文档站、静态博客、服务端渲染(SSR)的网站来说,这种模式完全够用,而且性价比极高。
莫潇羽@无忆研习社 在这里给大家一个选择建议:如果你要爬的是技术文档站(比如各种开源项目的 docs 站点)、新闻资讯类网站或者服务端渲染的网站,优先选 render: false;如果目标网站大量使用 JavaScript 动态加载内容,才需要使用 render: true。
2.3 URL 发现机制
/crawl 端点不只是简单地请求你给的那一个 URL,它有一套自动化的 URL 发现机制,可以从一个起始 URL 出发,自动找到整个网站的所有页面。
具体来说,当你使用默认的 source: "all" 配置时,爬虫按照以下顺序发现和处理 URL:
首先是你在请求中指定的起始 URL,爬虫会首先处理这个页面。接下来,爬虫会尝试查找并解析目标网站的 sitemap(站点地图),从中提取所有列出的 URL。Sitemap 通常位于网站根目录下的 /sitemap.xml 路径,它是网站管理者主动向搜索引擎和爬虫提供的页面索引文件,包含了网站中所有希望被发现的页面的 URL、最后修改时间、更新频率等信息。最后,爬虫会从已处理的页面中提取所有链接,发现那些既没有在起始 URL 中指定、也没有在 sitemap 中列出的页面。
你可以通过 source 参数来控制爬虫使用哪些发现方式。如果你只想爬 sitemap 中列出的页面,可以设置 source: "sitemap";如果只想通过页面内链接来发现页面,可以设置 source: "links"。
关于 URL 发现策略的选择,莫潇羽@无忆研习社 建议大家根据目标网站的特点来决定。对于维护良好的技术文档站(通常有完整的 sitemap),使用 source: "sitemap" 可以最快速、最准确地获取所有页面。对于内容组织比较混乱的网站(没有 sitemap 或 sitemap 不完整),使用 source: "links" 让爬虫通过页面间的超链接自行发现内容会更可靠。如果你不确定目标网站的情况,用默认的 source: "all" 就好——它会尽可能地利用所有可用的发现渠道。
另外需要注意的是,当使用 includeExternalLinks: true 时,爬虫会跟随页面中的外部链接跳转到其他域名的网站。这在某些场景下可能有用(比如分析一个网站的外链关系),但大多数情况下你不需要开启这个选项——它会大幅增加爬取量和运行时间。
2.4 异步任务模型
/crawl 端点采用的是异步任务模型,这是处理耗时操作的标准做法。整个流程分为两步:
第一步,你发送一个 POST 请求来发起爬取任务。Cloudflare 会立即返回一个 job ID,不会阻塞等待爬取完成。第二步,你用这个 job ID 发送 GET 请求来查询任务状态和结果。如果任务还在运行中,返回的状态会是 running;如果完成了,你就可以拿到所有爬取结果。
一个爬取任务最长可以运行 7 天,结果在任务完成后保存 14 天,之后自动删除。
任务过程中可能出现几种状态:running 表示正在运行;cancelled_due_to_timeout 表示超过了 7 天的最大运行时间;cancelled_due_to_limits 表示达到了账户的浏览器时间限制;cancelled_by_user 表示用户主动取消了任务。
2.5 合规机制:Signed Agent 与 robots.txt
这是 Cloudflare /crawl 端点与很多第三方爬虫工具最大的不同之处。
Cloudflare 的官方文档明确声明:/crawl 端点是一个 "signed agent"(签名代理),它会自我标识为机器人(bot),并且默认遵守目标网站的 robots.txt 指令和 Cloudflare 的 AI Crawl Control 规则。这意味着:
如果目标网站的 robots.txt 禁止了爬取,/crawl 会遵守这个限制。如果 robots.txt 中设置了 Crawl-delay(爬取间隔),/crawl 也会遵守。/crawl 不能绕过 Cloudflare 的反机器人检测或验证码(CAPTCHA)。
Cloudflare 在产品更新日志中特意强调了这一点,原话的大意是:这个端点被设计为一个合规的爬虫,目的是让开发者更容易遵守网站规则,而不是更容易违反它们。
这一点非常重要,因为它直接回答了社区中最常被问到的一个问题:"这个工具能绕过 Cloudflare 自己的 WAF 防护吗?"答案是否定的。
三、Browser Rendering 全套 API 端点一览
/crawl 只是 Cloudflare Browser Rendering REST API 最新加入的一个端点。实际上,整个 API 已经相当完善,涵盖了从单页内容获取到整站爬取的完整能力谱系。
莫潇羽@无忆研习社 在这里把所有端点整理出来,方便大家根据实际需求选择最合适的接口:
/content — 获取单个页面的渲染后 HTML 内容。适合只需要抓取一个或几个特定页面的场景。
/screenshot — 对指定页面进行截图,返回图片文件。适合网页视觉监控、竞品页面截图记录等场景。
/pdf — 将指定页面渲染为 PDF 文件。适合需要保存网页内容为 PDF 存档的场景。
/markdown — 将网页内容提取为 Markdown 格式。对于 AI 应用特别有用,因为 Markdown 是大语言模型最友好的输入格式之一。
/snapshot — 快照端点,相当于 /content 和 /screenshot 的合并版本,一次请求同时拿到 HTML 内容和页面截图。
/scrape — 结构化抓取端点,可以使用 CSS 选择器来精确提取页面中的特定 HTML 元素。
/json — 借助 Workers AI 的能力,用自然语言描述你想要提取的数据结构,自动从页面中提取结构化的 JSON 数据。
/links — 提取页面中的所有链接,返回链接列表。适合做链接分析或构建 URL 发现管道。
/crawl — 整站爬取端点(这次新增的重点功能),从起始 URL 出发,自动发现并爬取整个网站的内容。
值得注意的是,2026 年 3 月 4 日,Cloudflare 还将 Workers Paid 计划的 REST API 速率限制从每秒 3 个请求(每分钟 180 个)提升到了每秒 10 个请求(每分钟 600 个),这对高频调用场景是一个很实际的提升。
四、/crawl 端点的参数详解:可以做到多精细的控制
/crawl 端点的可配置程度远超很多人的第一印象。下面莫潇羽@无忆研习社 逐一拆解关键参数。
4.1 核心控制参数
url(必填):起始 URL,爬虫从这个地址开始工作。
limit:最多爬取多少个页面。默认值是 10,最大可以设置到 100,000。这个参数直接决定了爬取的广度。如果你只是想试试效果,用默认的 10 就够了;如果要爬一个大型文档站,可能需要设置到几百甚至几千。
depth:从起始 URL 开始,跟随链接的最大深度。比如设置为 3,意味着爬虫最多会从起始页面出发,经过三层链接跳转来发现新页面。
source:URL 发现方式。可选值包括 "all"(默认,综合使用 sitemap 和页面链接)、"sitemap"(只从 sitemap 发现页面)、"links"(只从页面内链接发现页面)。
4.2 输出格式参数
formats:指定返回内容的格式,可以是 "html"、"markdown"、"json" 中的一种或多种。你完全可以在一次爬取中同时获取多种格式的输出。
对于 AI 相关的应用场景(比如构建 RAG 知识库),建议使用 "markdown" 格式。Markdown 文本干净、结构清晰、token 效率高,非常适合直接喂给大语言模型。
如果选择了 "json" 格式,你还可以通过 jsonOptions 参数来配置 AI 提取的行为。jsonOptions.prompt 允许你用自然语言描述想要提取的数据结构,Cloudflare 的 Workers AI 会自动从页面内容中提取符合描述的结构化数据。
4.3 渲染控制参数
render:是否启用浏览器渲染。true(默认)会启动无头 Chrome 来处理每个页面;false 则直接发 HTTP 请求获取原始 HTML。前面已经详细分析过两者的区别。
rejectResourceTypes:一个数组,用来阻止浏览器加载不需要的资源类型。比如你可以设置 ["image", "media", "font"] 来跳过图片、音视频和字体文件的加载。这在使用 render: true 模式时特别有用——不加载这些资源可以显著加速页面渲染,降低浏览器时间消耗。
4.4 路径过滤参数
includePatterns:通配符数组,只爬取匹配这些模式的 URL。比如 ["**/docs/**"] 表示只爬取路径中包含 /docs/ 的页面。
excludePatterns:通配符数组,排除匹配这些模式的 URL。比如 ["**/changelog/**"] 表示跳过所有 changelog 页面。
这两个参数可以组合使用,实现非常精细的爬取范围控制。
4.5 增量爬取参数
这是一个容易被忽略但非常实用的功能。
modifiedSince:一个时间戳,只爬取在这个时间之后被修改的页面。适合定期更新知识库的场景——每次只爬取新增或更新的内容,跳过没有变化的页面。
maxAge:缓存有效期(秒)。如果一个页面在指定时间内已经被爬取过,就直接使用缓存结果而不是重新请求。Cloudflare 使用 R2(对象存储)来缓存爬取结果,maxAge 控制的就是这个缓存的有效时间。
这两个参数对于需要反复爬取同一个网站的场景(比如每天更新一次知识库)来说,能够显著节省时间和费用。
4.6 其他实用参数
includeExternalLinks:是否跟随外部链接。默认只爬取同域名下的页面,设置为 true 后会跟随外链爬取其他网站的页面。
authenticate:可以设置 HTTP 认证凭据,用于爬取需要基本认证(Basic Auth)的网站。
cookies:可以设置自定义 Cookie,用于爬取需要登录态的页面。
gotoOptions:精细控制页面加载行为,比如设置等待条件(等到某个网络请求完成或 DOM 达到某个状态后再抓取内容)。
五、实战操作:从注册到拿到数据的完整流程
下面莫潇羽@无忆研习社 带你一步步走通整个使用流程。即使你之前从来没用过 Cloudflare 的任何服务,也能跟着做下来。
5.1 前置准备
第一步:注册 Cloudflare 账号
访问 Cloudflare 官网(cloudflare.com),注册一个免费账号。注册过程很简单,提供邮箱和密码即可。
第二步:确认 Workers 计划
/crawl 端点同时支持 Workers Free 和 Workers Paid 两种计划。如果你只是想体验一下,Free 计划就够了(每天 10 分钟浏览器时间)。如果要正式使用,建议升级到 Paid 计划(每月 5 美元起,包含每月 10 小时浏览器时间)。
在 Cloudflare Dashboard 中,进入 Workers & Pages 页面,确认你的计划状态。
第三步:创建 API Token
这是很多新手容易卡住的环节。你需要创建一个具有 "Browser Rendering - Edit" 权限的自定义 API Token。
操作路径:Cloudflare Dashboard → 右上角用户图标 → My Profile → API Tokens → Create Token → Custom token
在权限配置中,选择 "Account" 级别,找到 "Browser Rendering",赋予 "Edit" 权限。创建完成后,妥善保存生成的 Token(它只显示一次)。
第四步:获取 Account ID
在 Cloudflare Dashboard 的主页面,你的 Account ID 显示在右侧栏中。后续所有 API 调用都需要用到这个 ID。
5.2 发起第一次爬取
准备就绪后,你可以用 curl 命令来发起你的第一次爬取任务:
curl -X POST \
'https://api.cloudflare.com/client/v4/accounts/{你的Account_ID}/browser-rendering/crawl' \
-H 'Authorization: Bearer {你的API_Token}' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://developers.cloudflare.com/workers/",
"formats": ["markdown"],
"render": false,
"limit": 20
}'
这个请求做了以下几件事:指定了起始 URL(Cloudflare Workers 的文档站)、要求输出 Markdown 格式、关闭了浏览器渲染(因为文档站是静态的)、最多爬 20 个页面。
如果一切正常,你会收到一个类似这样的响应:
{
"success": true,
"result": "c7f8s2d9-a8e7-4b6e-8e4d-3d4a1b2c3f4e"
}
result 字段中的那个 UUID 就是你的 job ID。
5.3 查询爬取结果
拿到 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 {你的API_Token}'
如果任务还在进行中,返回的 status 字段会是 "running"。任务完成后,你会在 records 字段中看到所有爬取到的页面内容。
你也可以通过添加 limit 和 offset 查询参数来分页获取结果,比如 ?limit=10&offset=0 获取前 10 条记录。
5.4 使用 JavaScript/Node.js 的完整示例
如果你习惯用代码来操作,下面是一个完整的 Node.js 脚本示例,展示了从发起爬取到获取结果的全流程:
const ACCOUNT_ID = '你的Account_ID';
const API_TOKEN = '你的API_Token';
const BASE_URL = `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/browser-rendering`;
async function crawlSite(targetUrl, options = {}) {
// 1. 发起爬取任务
const startResponse = await fetch(`${BASE_URL}/crawl`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: targetUrl,
formats: options.formats || ['markdown'],
render: options.render !== undefined ? options.render : false,
limit: options.limit || 50,
depth: options.depth || 3,
...options.extra
})
});
const startData = await startResponse.json();
if (!startData.success) {
throw new Error(`爬取任务启动失败: ${JSON.stringify(startData.errors)}`);
}
const jobId = startData.result;
console.log(`爬取任务已启动,Job ID: ${jobId}`);
// 2. 轮询等待任务完成
let status = 'running';
let attempts = 0;
const maxAttempts = 200; // 最多等待约10分钟(每次间隔3秒)
while (status === 'running' && attempts < maxAttempts) {
await new Promise(resolve => setTimeout(resolve, 3000)); // 每3秒查询一次
attempts++;
const checkResponse = await fetch(`${BASE_URL}/crawl/${jobId}?limit=1`, {
headers: { 'Authorization': `Bearer ${API_TOKEN}` }
});
const checkData = await checkResponse.json();
status = checkData.result.status;
console.log(`查询第 ${attempts} 次,状态: ${status}`);
}
if (status === 'running') {
console.log('任务仍在运行中,稍后再查询结果');
return { jobId, status: 'still_running' };
}
// 3. 获取完整结果
const resultResponse = await fetch(`${BASE_URL}/crawl/${jobId}`, {
headers: { 'Authorization': `Bearer ${API_TOKEN}` }
});
const resultData = await resultResponse.json();
return resultData.result;
}
// 使用示例
crawlSite('https://docs.example.com/', {
formats: ['markdown'],
render: false,
limit: 100,
depth: 3
}).then(result => {
console.log('爬取完成!');
if (result.records) {
console.log(`共爬取到 ${result.records.length} 个页面`);
// 处理每个页面的内容
result.records.forEach(record => {
console.log(`页面: ${record.url}`);
console.log(`Markdown 内容长度: ${record.markdown?.length || 0} 字符`);
});
}
}).catch(err => {
console.error('爬取出错:', err.message);
});
5.5 使用 Python 的简洁示例
Python 开发者可以使用 requests 库来调用:
import requests
import time
ACCOUNT_ID = "你的Account_ID"
API_TOKEN = "你的API_Token"
BASE = f"https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/browser-rendering"
HEADERS = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
}
def crawl_site(url, limit=50, depth=3, render=False):
"""发起一次整站爬取并等待结果"""
# 发起爬取
resp = requests.post(f"{BASE}/crawl", headers=HEADERS, json={
"url": url,
"formats": ["markdown"],
"render": render,
"limit": limit,
"depth": depth
})
job_id = resp.json()["result"]
print(f"任务已启动: {job_id}")
# 轮询等待
while True:
time.sleep(3)
check = requests.get(f"{BASE}/crawl/{job_id}?limit=1", headers=HEADERS)
status = check.json()["result"]["status"]
print(f"当前状态: {status}")
if status != "running":
break
# 获取结果
result = requests.get(f"{BASE}/crawl/{job_id}", headers=HEADERS)
records = result.json()["result"]["records"]
print(f"爬取完成,共 {len(records)} 个页面")
return records
# 调用示例
pages = crawl_site("https://docs.example.com/", limit=30, depth=2)
for page in pages:
print(f"URL: {page['url']}, 内容长度: {len(page.get('markdown', ''))}")
六、四个典型使用场景及对应配置
光讲参数可能还不够直观。下面莫潇羽@无忆研习社 给出四个非常具体的使用场景,以及对应的最优配置方案。
6.1 场景一:快速爬取静态文档站,构建 RAG 知识库
这是目前最高频的使用场景。很多团队在做 RAG(检索增强生成)应用时,需要把某个技术文档站的内容完整采集下来,切分成文本块后存入向量数据库。传统做法是用 Scrapy 编写爬虫脚本,或者用 Playwright 搭建一套无头浏览器管道——从编写代码到调试完毕,少说也要半天到一天的时间,遇到复杂的网站结构可能更久。
而使用 Cloudflare /crawl,整个数据采集流程可以压缩到几分钟。你只需要构造一个 JSON 请求,等待任务完成,就能拿到整个文档站的 Markdown 内容。拿到数据后,你可以直接用 LangChain、LlamaIndex 或其他 RAG 框架来做文本切分和向量化处理。
{
"url": "https://docs.example.com/",
"render": false,
"formats": ["markdown"],
"limit": 500,
"depth": 5,
"options": {
"includePatterns": ["https://docs.example.com/**"],
"excludePatterns": ["**/changelog/**", "**/release-notes/**"]
}
}
这段配置的关键点:render: false 因为文档站通常是静态的,不需要 JS 渲染;输出 Markdown 格式,可以直接用于后续的文本切分和嵌入(embedding)处理;通过 includePatterns 确保只爬文档站域名下的页面,excludePatterns 排除更新日志等不需要的内容。
在实际操作中,莫潇羽@无忆研习社 建议你在爬取前先访问目标文档站的 sitemap(通常是 https://目标域名/sitemap.xml),大致了解网站的规模和页面数量,然后再设置合适的 limit 值。设置过大的 limit 会浪费资源(如果网站只有 200 个页面,你设置 limit: 100000 是没有意义的),设置过小则可能遗漏内容。
另外,如果你的目标文档站使用了 Next.js、Nuxt.js 等框架进行服务端渲染(SSR),虽然页面的 HTML 内容是动态生成的,但在服务端已经完成了渲染,客户端拿到的就是完整的 HTML。这种情况下仍然可以使用 render: false,因为你不需要客户端的 JavaScript 来补充内容。判断方法很简单:用浏览器的"查看源代码"功能看一下,如果源代码中已经包含了你需要的文本内容,就可以用静态模式。
6.2 场景二:用 AI 提取产品目录的结构化数据
如果你需要从一个产品目录页面中提取产品名称、描述、规格等结构化数据,可以利用 /crawl 的 JSON 提取功能:
{
"url": "https://shop.example.com/products/",
"formats": ["json"],
"limit": 200,
"render": true,
"jsonOptions": {
"prompt": "提取每个产品的名称、价格、SKU编号、简要描述和产品分类"
}
}
这里 render: true 是因为很多商品展示页面依赖 JavaScript 来加载商品列表。jsonOptions.prompt 用自然语言描述了你需要的数据结构,Workers AI 会据此自动从页面中提取相应信息。
6.3 场景三:定期增量更新知识库
如果你已经完成了初次爬取,之后只需要每天更新变化的内容,增量爬取功能就派上用场了:
{
"url": "https://docs.example.com/",
"render": false,
"formats": ["markdown"],
"limit": 500,
"modifiedSince": "2026-03-15T00:00:00Z",
"maxAge": 86400
}
modifiedSince 指定只处理 2026 年 3 月 15 日之后更新的页面,maxAge 设置为 86400 秒(24 小时),表示 24 小时内已爬取过的页面直接使用缓存结果。这样每天运行一次,只会处理新增或变化的内容。
6.4 场景四:多格式同时输出,兼顾分析和存档
有时候你可能需要同时拿到页面的 Markdown(用于 AI 处理)和 HTML(用于存档或展示):
{
"url": "https://blog.example.com/",
"render": true,
"formats": ["markdown", "html"],
"limit": 100,
"depth": 2,
"options": {
"rejectResourceTypes": ["image", "media", "font"]
}
}
同时请求 Markdown 和 HTML 两种格式,通过 rejectResourceTypes 跳过图片、音视频和字体资源的加载来加速爬取过程。
七、定价策略深度分析:到底要花多少钱
定价是很多开发者最关心的问题之一。莫潇羽@无忆研习社 在这里做一个详细的梳理。
7.1 基础定价结构
Cloudflare Browser Rendering 的定价分为两种使用方式:
REST API 方式(包括 /crawl 端点):只按浏览器时长计费,每小时 0.09 美元。Workers Free 计划每天免费 10 分钟浏览器时间,Workers Paid 计划(每月 5 美元)每月免费 10 小时浏览器时间。
Workers Bindings 方式(通过 Puppeteer/Playwright 直接操控浏览器):同时按浏览器时长和并发浏览器数量计费。
对于 /crawl 端点来说,关键的省钱策略就在于 render 参数:
render: true 模式会消耗浏览器时间配额,按每小时 0.09 美元计费。render: false 模式在 Beta 期间完全免费,正式版之后按 Workers 标准定价计费(Workers Paid 计划每月包含 1000 万次免费请求)。
7.2 实际成本估算
我们来做几个不同场景的成本估算,帮助大家更直观地理解费用情况。
场景 A:爬取一个小型文档站(约 200 个页面,静态内容)
使用 render: false,在 Beta 期间完全免费。即使 Beta 结束后,按 Workers 请求量计费,200 次请求远在 Workers Paid 计划每月包含的 1000 万次免费请求额度之内。总成本:0 元。
场景 B:爬取一个中型网站(约 1000 个页面,需要 JS 渲染)
使用 render: true,假设每个页面平均需要 3 秒的浏览器时间。1000 个页面总共需要约 3000 秒(50 分钟)的浏览器时间。Workers Paid 计划每月包含 10 小时(600 分钟)的免费额度,50 分钟完全在免费范围内。总成本:仅需支付 Workers Paid 计划的基础费用 5 美元/月。
场景 C:高频爬取场景(每月爬取 50000 个页面,需要 JS 渲染)
使用 render: true,50000 个页面 × 3 秒 = 150000 秒 ≈ 41.7 小时。减去免费的 10 小时,需要额外付费 31.7 小时 × 0.09 美元/小时 ≈ 2.85 美元。加上基础费用 5 美元,总成本约 7.85 美元/月。如果同等规模使用 Firecrawl,按其标准套餐定价,50000 个页面可能需要花费数十甚至上百美元——差距是非常显著的。
场景 D:混合模式(部分静态页面 + 部分动态页面)
实际使用中,你可以根据目标网站的不同板块选择不同的渲染模式。比如文档站的主体内容用 render: false,而其中的交互式示例页面用 render: true。通过这种混合策略,可以在保证数据完整性的同时最大限度地控制成本。
需要特别提醒的是,以上估算基于"每个页面 3 秒浏览器时间"的假设。实际的浏览器时间取决于目标页面的复杂度——简单的静态页面可能只需要 1-2 秒,而 JavaScript 重度的 SPA 页面可能需要 5-10 秒。你可以通过 Cloudflare 返回的 X-Browser-Ms-Used 响应头来查看每个请求实际消耗的浏览器时间(以毫秒为单位),据此来优化你的爬取策略。
7.3 Free 计划的限制
需要注意的是,Workers Free 计划有一些额外的限制:每天 10 分钟的浏览器使用限制,最多 3 个并发浏览器实例。对于 /crawl 端点,Free 计划还有一些特定的限制,建议正式使用前查阅官方文档(developers.cloudflare.com/browser-rendering/limits/)了解最新详情。
如果你在 Free 计划下遇到了 429 错误(Too Many Requests),说明已经达到了当天的使用限制。你可以等到下一个 UTC 天重置后重新运行任务,或者直接升级到 Paid 计划来获取更充裕的使用额度。
八、与竞品的横向对比
市面上做网页数据采集的工具不少,下面莫潇羽@无忆研习社 选几个最有代表性的来做对比分析。
8.1 Cloudflare /crawl vs Firecrawl
Firecrawl 是目前 AI 数据采集领域最知名的工具之一。它的定位是"一站式 AI 爬虫 SaaS",提供了从单页抓取到整站爬取、再到 AI 结构化提取的完整功能链条。Firecrawl 最早由 Mendable 团队基于 TypeScript 开发,目前已开源,GitHub 上有大量 Star,社区生态也比较活跃。
从开发体验来看,Firecrawl 目前更胜一筹。它提供了成熟的 Python 和 Node.js SDK,还有社区维护的 Go、Rust、C# 版本。API 设计更加开发者友好,文档也更详尽。它的 /extract 端点支持用自然语言定义数据 schema,不需要写 CSS 选择器——这在很多场景下非常方便。此外,Firecrawl 还提供了 /map 端点,可以快速发现并返回一个网站的所有 URL,这对于需要先了解网站结构再决定爬取范围的场景非常实用。
但从成本角度看,Cloudflare 有明显优势。Firecrawl 按页面数计费,免费版有 500 次额度,之后的付费计划从每月约 16 美元(3000 credits)起步,更高级的计划价格可达每月数百美元。而 Cloudflare 的 /crawl 按浏览器时长计费,5 美元/月的 Paid 计划就能爬取大量页面。根据社区用户的实测数据,如果一次爬取 100 个页面大约消耗 5 分钟的浏览器时间,那么 Workers Paid 计划每月包含的 10 小时免费额度理论上可以支持爬取约 12000 个页面。这个性价比在高频爬取场景下远超 Firecrawl。
另一个 Cloudflare 的重要优势是它的全球边缘网络。Cloudflare 在全球拥有超过 300 个数据中心,浏览器实例可以在离目标网站最近的节点上启动,这在跨地域爬取时带来了更低的延迟和更好的性能。而 Firecrawl 的云端服务节点相对较少,对于海外网站的爬取速度可能不如 Cloudflare。
不过 Firecrawl 也有 Cloudflare 目前不具备的能力。除了前面提到的 Map 端点外,Firecrawl 对反爬绕过的支持更好——它的云端服务内置了代理轮换和一定程度的反爬绕过能力。而 Cloudflare /crawl 明确声明自己是一个"well-behaved bot"(行为良好的机器人),不会尝试绕过任何反爬保护。这一点在选择工具时需要根据你的具体需求来权衡。
如果你的目标网站没有开启严格的反爬保护(比如大多数技术文档站、开源项目官网、公共信息网站),Cloudflare /crawl 完全够用且成本更低。但如果目标网站有比较严格的反爬措施,你可能需要考虑 Firecrawl 或其他专业方案。
8.2 Cloudflare /crawl vs Crawl4AI
Crawl4AI 是一个开源的 Python 爬虫框架,在 GitHub 上拥有超过 61000 个 Star,专门为 AI 数据管道设计。它的核心优势是完全免费、可自托管、没有速率限制,使用 Apache 2.0 许可证,对商业使用非常友好。
从技术架构上看,Crawl4AI 是一个 Python 异步爬虫库,底层基于 Playwright 进行浏览器自动化。它支持多种输出格式(JSON、简化 HTML、Markdown),提供了丰富的文本切分策略(按主题、正则表达式、句子等),还支持自定义 JavaScript 注入来处理动态内容。它的"Adaptive Intelligence"功能是一个亮点——爬虫可以随着时间推移学习目标网站的页面结构,自动调整选择器策略,这在需要长期监控某个网站的场景下非常有价值。
Crawl4AI 还有一个独特的优势:它支持本地 LLM 来做数据提取。你可以使用 Llama、Mistral 等在本地运行的模型来处理爬取到的数据,整个过程不需要调用任何外部 API,数据不离开你的服务器。这对于金融、医疗等对数据隐私要求极高的行业来说是一个重要的考量因素。
但 Crawl4AI 的门槛也更高。它是一个需要自托管的库,你需要自己准备服务器、安装 Playwrig