Firecrawl(firecrawl.dev)是一个把“任意网页”变成“AI 可直接使用的数据”的 API 服务。 一句话定位:Search(搜索)、Scrape(抓取)、Crawl(整站爬取)、Extract(结构化提取)、Interact(浏览器交互) 的托管平台, 输出是干净的 Markdown、结构化 JSON、截图,而非原始 HTML。
本文基于其 GitHub 主仓库(firecrawl/firecrawl,AGPL-3.0 开源)的源码结构、官方 README 与 v2.5 发布博客整理。
一、它本质上在解决什么问题
网页是给“人 + 浏览器”看的:95% 以上的页面依赖 JavaScript 动态渲染,布局千奇百怪,还处处有反爬。 而 AI Agent 需要的是“干净、实时、结构化”的文本。这两者之间存在巨大的鸿沟。
Firecrawl 的生意就是填补这条鸿沟:在浏览器生态和 LLM 生态之间做一层“数据管道”。 官方对标的四个硬指标:
- 覆盖率:声称能覆盖 96% 的网页(含 JS 重页面),“no proxy headaches”
- 延迟:跨数百万页面 P95 延迟 3.4 秒,面向实时 Agent
- 输出质量:LLM-ready 的 Markdown / 结构化 JSON
- 托管:旋转代理、限流、JS 拦截、robots.txt 全部替你处理
公司背景:Y Combinator 支持,创始人 Eric Ciarla、Nicolas Camara、Caleb Peffer, 前身是 Mendable(客户包括 Snapchat、Coinbase、MongoDB)。主仓库 4 万+ star。
二、技术是什么:一套“多引擎 + 队列 + 转换 + 索引”的管道
从源码(monorepo:apps/api + apps/playwright-service-ts + apps/go-html-to-md-service 等)可以看清整体架构。
2.1 主 API:TypeScript + Express + 多种存储
apps/api 是核心服务,Node.js/TypeScript,Express 框架。
围绕它的是一大堆 worker 进程(queue-worker、extract-worker、index-worker、nuq-worker 等),
存储上混用了 Postgres(业务数据 + 队列)、MongoDB、Redis(限流/并发控制)和 ClickHouse(可观测性分析),
并用 Sentry + OpenTelemetry 做监控追踪。
2.2 核心机密:多引擎路由(Engine Router)
这是最值得讲的技术点。一次 scrape 请求进来,系统会根据 URL 特征和配置,把任务路由给不同引擎:
| 引擎 | 用途 |
|---|---|
fetch |
纯 HTTP 抓取,最快最便宜,只适用于静态页面 |
playwright |
通过 Playwright 微服务做完整浏览器渲染,处理 JS 重页面 |
fire-engine |
自研新引擎,两种模式:chrome-cdp(Chrome DevTools 协议,完整浏览器)和 tlsclient(TLS 指纹伪造客户端,不用浏览器) |
pdf / document |
PDF、DOCX 等文档解析 |
wikipedia |
走 Wikipedia Enterprise API |
x-twitter |
走 xAI 的 X API |
index |
命中语义索引缓存,秒回 |
exchange |
路由给第三方数据源合作伙伴(按条款和积分计费) |
关键取舍:完整浏览器渲染最贵最慢,TLS 伪造客户端又快又省但不支持 JS,纯 fetch 最快但只能抓静态页。 引擎路由就是在这三者之间做动态决策。v2.5 博客明确说,他们“从零构建了自己的浏览器栈”, 能自动检测页面如何渲染(静态 / 客户端渲染 / 服务端渲染),再选择最快的提取路径。
2.3 反检测技术:TLS 指纹伪造 + stealth
tlsclient 模式是技术含量最高的一块。反爬系统(Cloudflare 等)早已不只看 IP,
而是看 TLS 握手指纹(JA3/JA4)、HTTP/2 指纹、行为特征。
Firecrawl 用自定义 TLS 客户端在 TCP/TLS 层模仿真实 Chrome 的指纹,做到“不用浏览器却像浏览器”,
既绕过了指纹检测,又比开一个 Chromium 便宜一个数量级。
chrome-cdp;stealth 模式则是在真浏览器里注入 stealth 脚本,抹掉 navigator.webdriver 等头号特征。
配套还有 proxy-chain 代理轮换、user-agent 轮换、住宅 IP 池——这些在 apps/playwright-service-ts 里都能看到。
2.4 HTML → Markdown:专门用 Go 重写
把抓到的 HTML 转成干净 Markdown 不是小事:要剥离导航、页脚、广告、脚本,识别“主内容”,
还要保留表格、代码块、链接结构。早期实现基于 Mozilla Readability 的 JS 版本,
现在他们专门写了一个 Go 微服务 go-html-to-md-service,用的是 fork 自
JohannesKaufmann/html-to-markdown 的库(基于 goquery / golang.org/x/net/html)。
另有一个 Rust crate @mendable/firecrawl-rs 负责部分 JSON 提取逻辑。
Go/Rust 替换 JS 的目的只有一个:同样的转换逻辑,吞吐更高、成本更低。
2.5 异步任务系统:自研 NUQ 队列
抓取/整站爬取是慢操作,必须异步化。Firecrawl 用了一套自研队列 NUQ(New Queue), 后端可选 Postgres 或 FoundationDB(分布式 KV),配套 prefetch worker(预取)、reconciler worker(对账/恢复)、 以及 Redis、RabbitMQ。选择 Postgres 当队列,说明他们要的是“任务状态可查询、可审计、不丢消息”, 而不是内存级的高吞吐。
2.6 LLM 提取层 + 自研模型
结构化提取(extract)不是纯规则:先抓内容,再让 LLM 按用户提供的 JSON Schema 抽取字段。
模型层通过 Vercel AI SDK 接 OpenAI / Anthropic / DeepInfra / Fireworks / Google。
为了控制成本,他们还做了 /agent 端点(给定一句自然语言目标,Agent 自动搜索、导航、抓取、汇总),
并训练了自研 Spark 模型:spark-1-mini(便宜 60%)和 spark-1-pro(复杂任务)。
2.7 v2.5 的语义索引(Semantic Index)
2025 年 10 月 v2.5 的核心:把抓过的页面存成“完整快照 + 向量 embedding + 结构元数据”的索引, 目前已服务 40% 的 API 调用。效果:
- 命中索引的请求直接返回,速度接近瞬时
- 支持
maxAge参数:要么“实时抓取”,要么“返回最近一次已知的好版本” - 官网说法:等于给每个网站保存了历史状态,可以回放任意时刻的网页
2.8 生态:10+ 语言 SDK 与 MCP
Python / Node / Go / Java / Rust / Ruby / Elixir / .NET / PHP SDK,外加 CLI、
MCP Server(npx firecrawl-mcp,一行接入任何 MCP 客户端)、Claude Code / Codex 插件。
还提供 /agent-onboarding 让 AI Agent 自助注册拿 key。
三、难点是什么:为什么这个“简单 API”很难做
3.1 难点一:网页的异构性(数据面难题)
没有两个网站是一样的。你要同时处理:
- 纯静态 HTML、SSR、CSR(客户端渲染)、SPA、无限滚动
- PDF、DOCX、XLSX、图片里的文字
- 表格分页、弹窗、懒加载、登录墙、付费墙
- 同一种内容在不同网站结构完全不同
Firecrawl 的解法是“渲染方式自动检测 + 多引擎兜底”:先猜(静态 → fetch), 猜错就升级到浏览器渲染。但“猜”本身就要建立在海量页面数据上, 这就是为什么他们要把索引、渲染、提取做成一整套闭环。
3.2 难点二:反爬是场军备竞赛(对抗面难题)
这是整个行业最难、最“脏”的部分:
- Cloudflare、DataDome、PerimeterX 每天都在升级指纹检测:TLS/JA3/JA4、HTTP/2、字体、Canvas、WebGL、时区、行为轨迹(详见 3.2.1 深度案例)
- 无头浏览器特征、代理 IP 黑名单、验证码、挑战页、AI 爬虫迷宫(Cloudflare 2025 年推出的 AI Labyrinth,专门给 AI 爬虫喂假页面)
- 住宅 IP 池成本极高且不稳定
Firecrawl 的应对(tlsclient 指纹伪造 + stealth + 代理池 + 引擎路由)只能保证“暂时能用”。 这是一个永不停歇的猫鼠游戏,任何一次检测规则更新都可能让一批抓取失败, 所以他们的爬虫工程团队(Fire-engine、browser stack)才是真正的护城河,而不是 API 封装。
3.2.1 深度案例:指纹之战(JA3/JA4 与真实检测数据)
反爬的核心战场不是 IP,而是指纹(fingerprint)。这一节用真实数据和案例讲清楚:指纹是什么、怎么被检测、怎么被反制。
一、TLS 指纹是什么:一次握手的“笔迹”
任何 HTTPS 请求都要先做 TLS 握手,客户端发出的第一条消息叫 Client Hello。里面包含:TLS 版本、支持的加密套件(cipher suites)列表、椭圆曲线、扩展列表及顺序。
- JA3(2017 年 Salesforce 开源):把这些字段拼起来做哈希,得到一个 32 位指纹字符串
- JA4(2022 年 FoxIO 推出):改进了 JA3,把 ClientHello 扩展排序后再哈希,现代浏览器的唯一指纹数量大幅减少,更容易归类
不同的 HTTP 客户端指纹完全不同,因为底层 TLS 库不同:Chrome 用 Google 的 BoringSSL,Firefox 用 NSS,curl 默认用 OpenSSL。curl-impersonate 项目(GitHub 上最流行的指纹伪造工具)的 README 明确指出:为了模仿 Chrome,必须用 BoringSSL 重新编译 curl;模仿 Firefox 则要换 NSS。
我实测的数据(用 curl 8.4.0 访问 tls.peet.ws 指纹检测服务):
curl + OpenSSL 的真实指纹:
JA3: 771,4867-4866-4865-52393-52392-52394-49200-49196-49192-49188-49172-49162-159-107-57-65413-196-136-129-157-61-53-192-132-49199-49195-49191-49187-49171-49161-158-103-51-190-69-156-60-47-186-65-49169-49159-5-4-49170-49160-22-10-255,43-51-0-11-10-13-16,29-23-24-25,0
JA4: t13d497h2_0d8feac7bc37_7395dae3b2f3
注意 t13d497h2 前缀:t13 = TLS 1.3,d4 = 4 组 TLS 1.3 加密套件,97h2 = 支持 HTTP/2。这个指纹和真实 Chrome 的指纹一眼就能区分——Chrome 的 ClientHello 里 cipher suites 数量和顺序完全不同(这是 BoringSSL 决定的)。
除此之外还有 HTTP/2 指纹:HTTP/2 握手中的 SETTINGS 帧参数、header 顺序、流优先级,curl 和浏览器也完全不同。curl-impersonate 同样要修改这些设置才能过关。
二、检测方视角:Cloudflare 是怎么用指纹抓爬虫的
Cloudflare 官方文档(Bot Management,仅 Enterprise 客户)把 JA3/JA4 指纹作为独立的检测维度,还提供 JA4 Signals——不是单一指纹,而是一组基于 1 小时窗口的行为统计指标,官方示例 JSON 里包括:
ja4Signals: {
h2h3_ratio_1h: 0.988 // 该指纹 HTTP/2 vs HTTP/3 使用比例
browser_ratio_1h: 0.936 // 该指纹里"浏览器"特征请求占比
uas_rank_1h: 901 // 该指纹的 User-Agent 常见度排名
reqs_quantile_1h: 0.999 // 请求量分位(一个指纹请求量过大 = 可疑)
ips_rank_1h: 662 // 该指纹关联的 IP 数量排名
...
}
含义很直白:即使你伪造了指纹,Cloudflare 还会统计这个指纹的请求行为——请求量是否异常大、UA 是否常见、关联 IP 是否过多、浏览器特征占比是否正常。单一指纹的伪装在行为统计面前很难维持。
行业里的共识是反爬平台做多层级检测。X 上 @afinaio 的帖子总结过 Cloudflare 的评估栈:
Cloudflare does not block “a scraper” as one simple signal. It evaluates the full session stack:
- TLS 和 JA3/JA4 指纹
- HTTP/2 行为和 header 顺序
- IP 信誉和代理地理位置
- JavaScript 挑战和 Turnstile 信号
- Canvas、WebGL、字体和 ClientRects
- 跨会话的 cookie 一致性
- 节奏、导航和重复请求模式
三、反制方视角:Firecrawl 的 tlsclient 是怎么运作的
回到 Firecrawl 本身。它在开源仓库里对 TLS 指纹对抗的投入是看得见的:
源码中的真实配置(apps/api/src/scraper/WebScraper/utils/ENGINE_FORCING.md),可以让运营者按域名强制指定抓取引擎:
{
"google.com": ["fire-engine;chrome-cdp", "playwright"],
"*.cloudflare.com": "fire-engine;tlsclient;stealth",
"linkedin.com": "playwright",
"wikipedia.org": "fetch"
}
这个配置本身就是一篇技术说明:
- 普通站点用最便宜的
fetch - 需要 JS 渲染的(Google、LinkedIn)用完整浏览器(chrome-cdp / playwright)
- Cloudflare 保护的域名,强制上
tlsclient;stealth——即用 TLS 指纹伪造客户端 + stealth 模式,而不是浏览器
原因还是成本:Chromium 渲染一个页面要秒级时间 + 数百 MB 内存;TLS 客户端不需要启动浏览器,毫秒级、内存开销极小。tlsclient 就是 Firecrawl 版的 curl-impersonate。
四、真实案例:指纹战争中的“翻车现场”
案例 A:Playwright 裸跑遇到 Cloudflare 直接停
X 用户 @KTMudak(2026-08)分享:用 Playwright 抓网页,
“一旦开始访问某些服务,Cloudflare 就出现,一切都停了”。这是最常见的场景——
未做指纹伪装的 Playwright 默认行为特征(navigator.webdriver 标志、CDP 协议特征、
自动化时序)在 Cloudflare 面前几乎是裸奔。
案例 B:指纹与 UA 不匹配,比没有伪装更显眼
X 用户 @TonyWang_cn(2026-08)点评 Python 库 curl_cffi 时指出: “Chrome TLS fingerprint next to a Firefox User-Agent is a louder tell than none”—— TLS 指纹是 Chrome 的、User-Agent 却是 Firefox 的,这种自相矛盾反而更容易被识别。 伪造指纹必须全栈一致(TLS + HTTP/2 + UA + header 顺序 + 行为),缺一环就是破绽。
案例 C:无头浏览器的“最后一公里”
X 上 CloakBrowser 的推广帖(2026-05)展示了对抗的极限:用 33 个 C++ 级别的 Chromium 源码补丁 (不是 JS 注入),从源码层抹掉 CDP 泄露点、通过 reCAPTCHA v3(评分 0.9)、自动过 Cloudflare Turnstile。 这侧面说明:纯 JS 层的 stealth 脚本(改 navigator.webdriver 等)早就不够用了, 检测方已经深入到浏览器源码行为层面。
案例 D:指纹伪装解决了 TLS,还有 IP 层在等你
同样在那条帖子里:“bring your own proxies”——指纹干净了,但 IP 还是数据中心的,
照样被 IP 信誉库拦。@krunofm(2026-08)分享实战组合:
curl-impersonate + residential proxies(住宅代理)才能稳定过关,连 Mullvad VPN 都能放行。
案例 E:为什么“便宜”是 tlsclient 的胜负手
社区多次提到(@0xJokker、@QCXINT_ 等):“那些收 2000 美元/月的爬虫 API,底层就是 curl-impersonate 这套把戏”。 这句话点破了整个行业的成本结构:指纹伪造是开源技术,难的是把它规模化、自动化、和代理/渲染/提取串成流水线。 Firecrawl 的 tlsclient 引擎 + 引擎路由 + 语义索引,就是把这套开源技术产品化的结果。
小结
指纹之战不是“一个指纹”的对决,而是多层信号的攻防:
攻击方 检测方
TLS 指纹伪装 (JA4) ←→ TLS 指纹 + JA4 Signals 行为统计
HTTP/2 伪装 ←→ HTTP/2 SETTINGS / header 顺序
stealth 脚本 ←→ navigator.webdriver / CDP leaks / Canvas / WebGL
代理轮换 (住宅/移动 IP) ←→ IP 信誉 / ASN 归属 / 地理位置
请求节奏控制 ←→ 请求量分位 / 访问路径模式
每一层都能被检测,每一层也都能被伪装,但伪装必须全栈一致、行为必须像人。 这就是为什么 Firecrawl 这类服务要养一个专门的爬虫工程团队: 真正的护城河不是“伪装一层指纹”,而是让整个抓取流水线在多层检测下长期稳定存活。
3.3 难点三:提取质量与“干净”的定义(质量面难题)
“能抓到 HTML”和“给出 AI 可用的数据”之间差着十万八千里:
- 主内容识别:去掉导航、页脚、推荐位、广告,识别正文起点
- Markdown 保真:表格、代码、嵌套列表、链接不能丢
- 结构化抽取:LLM 会幻觉、会漏字段、会格式不符——需要 schema 校验 + 重试 + 降级策略
- 一致性:同一个字段(如价格、日期)在不同网站格式完全不同,抽取规则必须鲁棒
这也是为什么他们要专门写一个 Go 转换服务 + 自研 Spark 模型: 质量问题是“每提升一个百分点都要投大量工程”的问题。
3.4 难点四:规模、延迟与成本三者不可兼得(经济学难题)
- 浏览器渲染:每个 Chromium 实例吃几百 MB 内存,慢(秒级)且贵
- TLS 伪造客户端:快、省,但不支持 JS,覆盖率有限
- 索引缓存:瞬时返回,但有新鲜度问题
P95 3.4 秒这个数字背后是“预取 + 多引擎决策 + 索引命中”的组合拳。 纯靠堆浏览器实例,成本会随规模线性爆炸,根本做不成生意。 v2.5 自研浏览器栈、语义索引的本质,都是成本结构优化。
3.5 难点五:新鲜度 vs 缓存的矛盾(产品面难题)
索引让 40% 请求秒回,但网页会变:价格改了、文章更新了、页面下线了。
maxAge 参数解决的是这个权衡——但“多久算过期”“哪些页面值得缓存”“索引失效如何触发”
都需要基于真实流量做决策,否则会陷入“要么数据旧、要么成本高”的两难。
3.6 难点六:合规与信任(法律面难题)
- 默认遵守 robots.txt(源码里有
shouldCheckRobots.ts;“lockdown” 模式下连 robots.txt 都不请求) - 网站 ToS、版权、隐私(GDPR)——抓取是法律灰色地带,Firecrawl 必须把责任边界和合规说明写清楚
- 企业客户要求 SOC 2 Type 2、数据保留策略、零保留模式(zeroDataRetention)
法律风险不能靠技术解决,但技术(robots 尊重、数据最小化、审计)决定了产品能不能卖给企业。
3.7 难点七:规模化运营(工程面难题)
- 任务队列不能丢消息、不能死锁(NUQ + reconciler 对账)
- 多租户的限流、并发配额、按 credit 计费(billing 服务)
- 全球多地代理出口、时区/语言/移动端模拟
- 可观测性:数百万请求的失败归因,靠 ClickHouse + Sentry + OpenTelemetry 支撑
四、一句话总结
Firecrawl 表面是一个“网页转 Markdown”的 API, 实际上是一套 多引擎路由(静态抓取 / 浏览器渲染 / TLS 指纹伪造)+ 自研异步队列 + Go/Rust 内容管道 + LLM 提取 + 语义索引 的复杂系统。
真正的难点不在“发 HTTP 请求”,而在三件事:
- 反爬军备竞赛(指纹对抗,永无终点)
- 质量与成本平衡(浏览器渲染太贵,必须用 TLS 客户端 + 索引 + 自研模型把成本打下来)
- 规模化可靠性(百万级请求下的队列、限流、新鲜度、合规)
这也是为什么这个赛道看起来“人人能做”,但真正能稳定规模化赚钱的玩家很少—— API 是薄的,工程是厚的。
参考资料
- GitHub 仓库:https://github.com/firecrawl/firecrawl(AGPL-3.0,源码结构:apps/api、playwright-service-ts、go-html-to-md-service、nuq-postgres)
- 官方 README:https://github.com/firecrawl/firecrawl/blob/main/README.md
- v2.5 发布博客(自研浏览器栈 + 语义索引):https://www.firecrawl.dev/blog/the-worlds-best-web-data-api-v25
- 文档:https://docs.firecrawl.dev
- MCP Server:https://github.com/firecrawl/firecrawl-mcp-server
指纹章节引用来源(真实数据与案例):
- TLS 指纹实测:https://tls.peet.ws/api/all(curl 8.4.0 + OpenSSL 的 JA3/JA4 实测数据)
- JA4+ 指纹标准:https://github.com/FoxIO-LLC/ja4(JA4 原理与 JA3 的改进)
- curl-impersonate(TLS/HTTP2 指纹伪造技术原理):https://github.com/lwthiker/curl-impersonate
- Cloudflare Bot Management JA3/JA4 官方文档(含 JA4 Signals 行为指标):https://developers.cloudflare.com/bots/concepts/ja3-ja4-fingerprint/
- Firecrawl 引擎配置文档(
*.cloudflare.com → tlsclient;stealth真实配置):https://github.com/firecrawl/firecrawl/blob/main/apps/api/src/scraper/WebScraper/utils/ENGINE_FORCING.md - 案例 A(Playwright 遇 Cloudflare 受阻):https://x.com/KTMudak/status/2090837667718017306
- 案例 B(指纹与 UA 不匹配反而暴露):https://x.com/TonyWang_cn/status/2091157166799589462
- 案例 C(源码级 Chromium 补丁/CloakBrowser,7 层检测):https://x.com/Voidmob_com/status/2059776062435869105
- 案例 D(curl-impersonate + 住宅代理实战):https://x.com/krunofm/status/2088318067709202699
- 案例 E(多层检测栈/行为统计):https://x.com/afinaio/status/2089361607524757526
注:96% 覆盖率、P95 3.4s、索引服务 40% 调用等数据来自 Firecrawl 官方 README 与博客自述,未经第三方独立验证;X 帖子均为发布时可见内容,观点属于原作者。