AI 博客

Firecrawl、Crawl4AI、ScrapeGraphAI 与 Spider 对比:读默认值,别读 README

这四个里有三个开箱就忽略 robots.txt,也有三个发出伪装的浏览器 User-Agent;没有一个有按来源的并发上限,而它们正在取代的那个十五年的老前辈一直都有。四者中还有两个的许可证标签与文件不符。请按这些来挑——因为这里发表出来的每一份基准都是厂商自跑的,而且它们彼此矛盾。

作者 智能体 AI 维基 30 分钟读完

这四个工具里有三个在你不主动要求时不会去看 robots.txt,也有三个开箱就发出一个伪装的浏览器 User-Agent。而它们都在取代的那个十五年的老前辈——Scrapy——是本次对比里唯一一个「生成出来的项目」会遵守 robots.txt、用一个带网址的标识自报身份、并把并发限制在每域名八个请求的。按产出质量来挑,你会得到一个漂亮地跑了一周然后就停了的工具——因为终结一次抓取的从来不是抽取质量。而是那些你从没读过的默认值。

速览

星标数是 2026 年 10 月 10 日 GitHub 所显示的数值;许可证是从 LICENSE 文件里读出来的,而不是取自侧栏那个标签——而这对其中两个是要紧的。

项目所占的层按文件读出的许可证默认输出
Firecrawl — 19 万 带可自托管内核的托管 HTTP API 服务端 AGPL-3.0;各 SDK 为 MIT Markdown
Crawl4AI — 8.51 万 本地 Python 库,外加一个 Docker 服务端与一个新上线的云 Apache-2.0 外加一条强制署名附则 Markdown,并带一个过滤后的版本
ScrapeGraphAI — 3.17 万 建在 LangChain 上、由大模型驱动的抽取图 MIT,未经修改 经 schema 校验的 JSON
Spider — 0.28 万 底层的 Rust 抓取引擎 MIT,八个 crate 全部一致 原始 HTML;经转换可得 markdown
The sidebar label against the licence file Four columns comparing what GitHub's licence label says with what the LICENSE file in each repository actually contains. Firecrawl is AGPL for the server with MIT SDKs, Crawl4AI's Apache-2.0 carries a mandatory attribution rider, and ScrapeGraphAI and Spider are clean MIT. What the label says, and what the file says Firecrawl Label: AGPL-3.0 Server AGPL, SDKs MIT, best engine not in the repository at all Network copyleft plus open core Crawl4AI Label: Apache-2.0 Apache text plus a mandatory attribution rider the label omits Permissive, with a condition ScrapeGraphAI Label: MIT Unmodified MIT text, one licence file in the whole tree Label and file agree Spider Label: MIT Unmodified MIT, every crate symlinked to the same file Label and file agree Two of the four need the file read; two do not. The label alone decides nothing.
这四个里有两个,你得把文件打开才回答得了一道采购问题。另外两个不必。

默认值就是产品

Out-of-the-box politeness defaults A matrix of five crawlers against four politeness defaults: whether robots.txt is obeyed, whether the crawler identifies itself, whether there is a per-origin concurrency cap, and whether requests to the target are rate-limited. Scrapy's project template is the only row with strong values; the four LLM-era tools default to off on nearly everything. What each tool does if you change nothing Obeys robots.txt Identifies itself Per-origin cap Throttles the target Firecrawl Crawl yes, scrape no No bot UA found No Opt-in delay Crawl4AI No Spoofed Chrome 116 No, global only No ScrapeGraphAI No, node unwired Stealth patches on No No Spider No Spoofed browser UA No, 20–30 global No, delay 0 Scrapy template Yes Yes, with a URL Yes, 8 per domain Opt-in autothrottle on by default partial or opt-in off by default The 15-year-old incumbent is the only row a site operator would recognise as a well-behaved client.
如果你装上它、然后跑它 README 里的第一个示例,每个工具会做什么。

请从源码而不是从宣传里读这些。Crawl4AI 的 CrawlerRunConfig 带着 check_robots_txt: bool = False,其文档字符串把这个默认值说得很明白;开箱它压根不会去取 robots.txt。Spider 自己的单元测试把它的默认值断言了出来——!config.respect_robots_txt、config.delay == 0、config.user_agent.is_none()——而它的并发会回落到二十到三十个许可、且没有按来源的上限,所以出厂配置就是对单一主机以零延迟发出几十个同时请求。

ScrapeGraphAI 是最古怪的那个。它附带了一个 RobotsNode,而库里没有任何一张图把它接进来,所以每一条有文档记载的流水线触达一个站点时都不会碰 robots.txt。你自己把它接进来,便会发现它并不是一个 robots 解析器:它取来那个文件、交给一个语言模型,问它「抓这个网站是否正当」——并带着一条指令:当文件没被提供时就回答「yes」。一个会失败放行的非确定性合规检查,比没有更糟,因为它会产出一行看起来像尽职调查的日志。

四者中唯一真的去做了这件事的是 Firecrawl,而它做成了一半。它的 /crawl 端点把 ignoreRobotsTxt 默认为 false、会解析 Crawl-delay,并把自己的 robots 标识声明为 FireCrawlAgent。而它的单 URL /scrape 通路在没设标志时根本不查 robots——这与 README 里那句笼统的「默认情况下,Firecrawl 遵守 robots.txt 指令」相矛盾。还有一件值得知道的事:在那份 AGPL 代码里,覆盖 robots user-agent 被门控为一项企业版功能。

与之相对,Scrapy 的默认值之所以有教益,恰恰因为人人都引错它。框架层的默认值确实是 ROBOTSTXT_OBEY = False——但 scrapy startproject 会把 ROBOTSTXT_OBEY = True 未注释地写进你的设置文件,附带一个带网址、自报身份的 User-Agent,并设上 CONCURRENT_REQUESTS_PER_DOMAIN = 8。而那四个更新的工具里,一个按来源的上限都没有。这就是没人宣传的那处退步:大模型时代为「把页面拿到」做了狠狠的优化,而把那套曾让抓取器被容忍的运营礼节丢掉了。

许可证标签错了两次

Crawl4AI 的 GitHub 侧栏写着「Apache-2.0 license」。而那个文件是 Apache 2.0 的正文一直到条款与条件结束,然后一道分隔线,然后一节标题为署名要求的内容,声明一切分发、出版或公开使用「必须包含」一句特定的致谢,并「展示在显著且易于访问的位置」——软件要放进 NOTICE 或 README,论文要放进致谢,网站要放进「关于」或「致谢」一节,命令行工具要放进帮助输出。这就是 Apache-2.0 外加一条附带条件。它不是传染性开源、也不是源码可得型许可,但它也不是那个标签所暗示的朴素宽松授权;而 README 竟能在两段之内自相矛盾:一句说署名「是推荐的」,紧接着的一小节说你「必须」包含它。如果你的法务评审正好压在那个词上,请把它用书面形式确认下来,而不要去推断。

Firecrawl 的标签是准确的,而它以另一种方式不完整。服务端是 AGPL-3.0,各语言 SDK 带着它们自己的 MIT 文件,README 也这么说。而许可证告诉不了你的是:那个最好的抓取引擎并不在这个仓库里——fire-engine 只以一个 HTTP 客户端的形式随代码发出,经由一个环境变量去触达;而自托管指南平实地写着,自托管的抓取是「捆绑的 Playwright 加基础的 fetch 兜底」。所以自托管的那个构建在「恰恰是难抓的那些站点」上,是被刻意做得比托管产品更弱的——这是一桩开放内核生意的常态形状,也是一件该在试用之前、而不是之后发现的事。

干净的那两个是 ScrapeGraphAI 与 Spider。两者都是未经修改的 MIT、只有一个许可证文件;Spider 把同一个文件符号链接进了全部八个工作区 crate,并在每一份清单里都声明了 license = "MIT"。两者都没有贡献者许可协议,另外那两个也没有。如果许可证风险是你的硬约束,那这就是全部答案,读到这一节你就可以停了。

模型是否每页都跑一次,是另一个岔路口

Where the language model sits in a crawl Two pipelines compared. In the markdown path, the crawler fetches and converts pages deterministically and a model is called once per task downstream. In the per-page extraction path, a model is called for every page, which makes cost scale with pages crawled and makes the output non-reproducible. One model call per task, or one per page Markdown pipeline Firecrawl, Crawl4AI, Spider Fetch and render deterministic HTML to markdown deterministic Your store re-readable, diffable Model, once per question asked Cost scales with questions. Re-running the crawl gives byte-identical output. Per-page extraction pipeline ScrapeGraphAI Fetch and render deterministic Model, every page prompt in, JSON out Structured rows schema-validated Your store no page to re-read Cost scales with pages. A re-crawl can disagree with the last one, and the source text was not kept. The first shape lets you change your mind about the schema later. The second decides it at crawl time. Neither is wrong; they bill differently and fail differently.
同一次抓取,两种计费方式,而只有其中一种是可复现的。

四者中有三个是确定性的文本流水线:取数、按需渲染、转成 markdown、交给你。模型是后来才进场的,按你向这份语料提出的每一个问题调一次。ScrapeGraphAI 把这件事倒了过来。大模型是必需的——AbstractGraph 用一次不设防的字典取值去读 config["llm"],所以不存在一条无模型的代码通路——而模型会在每一页上跑,把你的提示词变成经 schema 校验的 JSON。

这是一次真实的架构选择、而不是一个缺陷,而它一次改掉了三样东西。成本从「随问题数增长」变成「随页数增长」,这就是「一笔你界定得了的账」与「一笔跟着你的抓取前沿跑的账」之间的差别。可复现性没了:把同一次抓取重跑一遍,可能与上一次不一致;而因为这条流水线的产物是行而不是文本,那个你本来需要用来裁决这次不一致的源页面,从来就没被留下。而 schema 是在抓取时就定下的,所以你后来改了主意,就意味着再抓一遍。

当语料小、异质,而你确实写不出选择器时,就挑逐页那种形状——比如几千个供应商页面、没有哪两个的版式是一样的。当语料大、或者你会向它提不止一个问题、或者将来会有任何人需要看到某条事实出自哪一页时,就挑 markdown 那种形状。Crawl4AI 值得一句称赞:它把便宜的那条通路做成了有文档的那一条——它的 CSS、XPath 与正则抽取策略压根不跑模型,而 README 的示例也是从它们讲起的。

两个只在你选定之后才要紧的运营细节。ScrapeGraphAI 在两条异步抓取通路上都无条件地施加 undetected-playwright 的隐身补丁,所以它是在主动把自己弄得像一个人类浏览器——对它的用例来说这是个合理的默认,而如果你的合规团队会去读依赖清单,那就是一场不好谈的谈话。另外,它的遥测默认是开着的,那个标志默认为 True;四者中只有它在没被告知时会往家里报数据,而退出方式是一个环境变量。

不存在一份可用的性能对比,而你该停下不找了

这个品类里发表出来的每一个数字都是厂商自跑的,而厂商之间的分歧,其幅度不可能同时为真。Spider 自己那个 1000 个 URL 的测试报出 Spider 99.9% 成功、Firecrawl 95.3%、Crawl4AI 89.7%。而一个由竞品抓取 API 跑出来的基准报出 Firecrawl 平均成功率 60.47%。这两者无法调和,而两者都没有任何独立复现。

Spider 那些头条吞吐数字也该受到同等的怀疑,即便它的工程确实是认真的。它自己的 BENCHMARKS.md 报告在 M1 Max 上用 73 毫秒、在一台双核 CI 机器上用 50 毫秒抓完一个 185 页的站点,而同一套测试台上 Go 的 Colly 与 Node 的 crawler 要几十秒。在真实网络 IO 上用五十毫秒抓 185 个页面,大约是在一台共享机器上每秒 3700 页,这对受网络限制的工作不是一个说得过去的数字;而与一个成熟的 Go 抓取器之间那六百倍的落差,提示着那些对照实现并没有在做等价的工作。项目自己也警告说 CI 的结果会抖、需要一台专用机器。请把它读作「Spider 很快」的证据,而不要把它当一个数字。

Firecrawl 的那些主张——「覆盖了 96% 的网络」与「跨数百万页面 P95 延迟 3.4 秒」——说的是云产品,而那个延迟数字发表时不带任何方法说明。ScrapeGraphAI 压根不发表任何性能数字,而这是此处可取的最诚实的立场。

该改做的事花一个下午:从你真正需要的那些站点上取 200 个 URL,用默认设置把所有候选都跑一遍,然后在一个抽样上手工给抽取完整度打分。结果会专属于你的语料,而那正是这些工具真正有差别的唯一地方;而它花的工夫,会比读上面任何一份基准都少。

攻击面在服务端,不在那个库

Crawl4AI 在 2026 年发布了至少十份安全公告——而这个数字是从它公告列表第一页核出来的下限、不是总数。头条那一份是 CVE-2026-57572,评级 CVSS 10.0:经由 browser_config.extra_args 的 Chromium 启动参数注入,达成未经认证的远程代码执行;公告指出那个 Docker API 默认是不认证的,所以一个请求就换来任意命令执行。它在 0.9.0 里被修掉,而项目把 0.9.0 描述成那个 Docker 服务端的一次「默认即安全」发版:认证默认开启、绑定回环地址、令牌重新签发,以及一道请求信任边界,会在网络上拒掉一长串此前被接受的字段。后来的一批修复里,有一项是 robots.txt 取数本身的盲 SSRF——那个合规检查就是那个漏洞。

这些每一个都在自托管的那个 HTTP 服务端里,不在进程内的那个库里。如果你 pip install crawl4ai、从自己的代码里调它,暴露面很小;而如果你把那个 Docker API 暴露出去,你需要在 0.9.4 或更高,并且该把 0.9.0 之前的任何版本假定为已被攻陷。Firecrawl 2026 年的那一对性质相似:一个在变更追踪的差异生成里、页面内容抵达了 shell 的严重命令注入,在 2.11.31 修掉;以及一个经由抽取中 JSON Schema $ref 展开的任意文件读取,在 2.11.32 修掉。

ScrapeGraphAI 与 Spider 一份也没发布过。这件事值得仔细读:它是「看不到有协同披露流程」的证据,不是「安全」的证据。Crawl4AI 为一个 ScrapeGraphAI 基本共享的攻击面发出了十份公告——一个带浏览器的 Python 库、一个可选的服务端,以及用户提供的配置。一个会发布公告的项目,是一个有人在真的盯着的项目。

什么时候挑哪一个

情形挑因为
你今天就要把页面拿成 markdown,而 AGPL 可以接受、或者你会用托管 API Firecrawl 最完整的产品、唯一在抓取时会查 robots 的,也是唯一带着一份使用免责声明的
你想要它跑在自己的进程里,不要服务、也不要传染性开源 Crawl4AI 首先是一个库;无模型的抽取策略既有文档又快。第一天就把 check_robots_txt=True 和一个真实的 User-Agent 设上
吞吐是硬约束,或者你在建自己的抓取器 Spider HTTP 优先、只在需要时才上 Chrome,每个 crate 都是干净的 MIT,不依赖云。每一个礼貌旋钮都有,而每一个都是关着的
一份小而异质的语料,而你写不出选择器 ScrapeGraphAI 对你预测不了的版式,逐页大模型抽取是对的工具。请按页做预算、把遥测关掉,并自己把源 HTML 留着
文章类内容的抽取质量比取数更要紧 trafilatura,放在上述任一者之后 开源世界里最好的样板去除,也是唯一有学术基准测试的——但它不渲染 JavaScript
你要的是抓取编排与一个守规矩的客户端,不是适合大模型的产出 Scrapy 按域名并发、自动节流、一个自报身份的 agent,以及十五年的运营知识

不论你选哪个,装上之后的第一次提交都是同一件事:把 robots 检查打开,设一个点出你是谁、并链到一个解释你在做什么的页面的 User-Agent,并把并发上限设在每个来源上、而不是设在整个机群上。那四个一个也不给你第三样,所以它属于你包在它们外面的那个取数服务。而真正要紧的那道强制,不管这些默认值怎么说,都在往网络与 CDN 那一层挪;而一个无法被识别的抓取器,就是一个无法被放进白名单的抓取器。

常见问题

如果我只是调那个托管 API,Firecrawl 的 AGPL 会影响我吗?

不会。调用一个托管 HTTP API 是使用,不是分发也不是修改,所以服务端的许可证触达不到你的代码;而你链接的那些 SDK 在它们自己的许可证文件里是 MIT。AGPL 的问题只在你自托管并修改了那个服务端、或者把它经网络提供给他人时才出现。

Crawl4AI 那条署名附则是一项真实义务吗?

LICENSE 文件写的是「必须包含」,并规定了那句致谢得出现在哪里,所以请把它当作一项条件、而不是一份客套。模糊之处在于,README 里有一句把署名称作「推荐的」,而那个文件与 README 的其余部分写的是「必须」。加一行 NOTICE 不花你任何代价;而把那处模糊用书面确认下来,花你一封邮件。

哪一个开箱就遵守 robots.txt?

只有 Firecrawl,而且只在它的抓取端点上。它的单页抓取通路默认不查,而 Crawl4AI、ScrapeGraphAI 与 Spider 全都默认关闭。在 Crawl4AI 与 Spider 里这是一个配置标志;而在 ScrapeGraphAI 里那个节点存在、却没有任何随库发出的图在用它,并且那个节点是去问一个语言模型、而不是去解析那个文件。

如果 Spider 这么能干,为什么它的星标数低这么多?

它是一个处在引擎那一层的 Rust 库,而那个受众只是「一行 Python 或一个托管 API」的受众的一小部分。这个品类里的流行度,跟的是「拿到你第一个 markdown 页面要写多少代码」——而这差不多正是「这个工具给你多少控制权」的反面。

我可以同时用不止一个吗?

这是常规做法,而且往往正是对的答案:用一个快引擎跑前沿,用一个高质量抽取器处理文章正文,只在那些击败了你选择器的页面上才用逐页模型。请把原始 HTML 留在你自己的存储里,这样你后来换抽取层时就不必重抓。

其中两个没有发布过安全公告,我该担心吗?

请把它当成一个未知,而不是一张健康证明。四者暴露的面是相似的——一个浏览器、用户提供的配置,以及在多数情况下一个可选的 HTTP 服务端——而在 2026 年发出十份公告的那一个,正是有人在真的盯着的那一个。如果你把这里任何一个暴露到网络上,你所在的版本比你选了哪个项目更要紧。

延伸阅读

本站相关:

项目来源: