几乎每一篇“最佳开源爬虫”盘点都有一个不太起眼的毛病:它们根本没有让这些工具在同一批页面上跑一遍。Scrapy 可能是在新闻文章上测的,Playwright 可能是在某个电商演示页上跑的,Colly 则可能只是作者随手找来的页面——然后它们就被放在一起横向排名,好像这些数字真的能直接对比一样。这样的排名,告诉你的其实是页面差异,不是工具差异。
所以我做了这件最朴素、也最无聊的事:我搭了一套相同的测试样本,把 9 款工具全部丢进去跑了一遍。样本包括:一个静态商品目录、一个由 JavaScript 渲染的目录、一个被导航栏和页脚杂项包围的文章、一条刻意返回 HTTP 500 的错误页面、一个小型内部链接爬取图谱,以及两个公开练习站点。Ground truth 一样,衡量方式一样,每一次运行都一致。脚本和原始输出都放在这个公开基准仓库里,你可以自己重新跑。最终结果并不是那些盘点文章承诺的整齐排行榜——因为根本没有唯一冠军。这里只有三类任务,而这 9 款工具几乎自然地分成了三组。
这套测试是怎么跑的,以及我先说明的一个限制

每个工具都面对同样的样本形态:两页共 12 个静态商品、延迟后由 JavaScript 注入的 8 个商品、一个被导航栏和页脚模板包裹的文章(其中只有 3 段真正正文)、一个故意触发的服务器 500 错误,以及一张内部链接图。正是这种设计,让结果能够对齐——“8/8 动态商品”在 Puppeteer 或 Crawlee 跑出来时,含义完全一致。
这里有一个很多盘点都会跳过的边界条件。每个工具包都对应自己的样本副本,所以绝对字符数在工具之间不能直接比较——它们只能作为“工具内部”的信号,不能当作跨工具分数来看。真正可以比较的是召回率(把它看成一种通过率)、JavaScript 成功/失败情况,以及结构化行为。还有一个类似的范围说明:Crawl4AI 的静态目录测试只覆盖了第一页,所以它的 6/6 是在更窄范围内的完整召回;而其他工具抓取了两页,拿到 12/12——这是范围更小,不是漏掉了一半。完整推理过程,逐个样本都写在方法说明里。
再补一个说明,免得数字被误读。每个工具包里也带着一个临时研究分数,但我刻意没有把它们做成排名表。它们只是内部辅助,用来检查每个工具是否符合自己的证据,而不是联赛积分榜——如果把它们公布出来,反而会重现这次实验本来就是为了避免的“虚假精确”问题。这篇文章是对测试结果的综合判断,不是记分牌。
全部工具,一张测试台上看清楚
沿着这张表往下看两列——“支持 JS 渲染?”和“内置爬取队列”——三类任务几乎自己就浮现出来了。
| 工具 | 语言 | 支持 JS 渲染? | 静态召回 | 结构化输出 | 内置爬取队列 | 安装重量 | 许可证 |
|---|---|---|---|---|---|---|---|
| Crawl4AI | Python | 支持(浏览器) | 6/6(第一页) | CSS schema | 内置 BFS/DFS | 较重(2 套浏览器栈) | Apache-2.0 |
| Firecrawl | 自托管 | 支持(playwright-service) | 完整 Markdown | 支持 | /v1/crawl | 最重(6 个容器) | AGPL-3.0 |
| trafilatura | Python | 不支持 | 3/3 文章 | 不支持(仅文本) | 不支持 | 轻量 | Apache-2.0 |
| Crawlee | Node/TS | 可选引擎 | 12/12 | 通过抽取实现 | 支持(RequestQueue) | 中等(约 +80 MiB) | Apache-2.0 |
| Playwright | Node/多语言 | 支持 | 12/12 | 手动实现 | 不支持(需手写 BFS) | 中等(浏览器) | Apache-2.0 |
| Puppeteer | Node | 支持(Chrome) | 12/12 | 手动实现 | 不支持(需手写 BFS) | 中等(浏览器) | Apache-2.0 |
| Scrapy | Python | 不支持 | 12/12 | Feed 导出(JSON/CSV/XML) | 支持(内置) | 中等(Twisted 依赖) | BSD-3 |
| Colly | Go | 不支持 | 12/12 | 通过回调实现 | 深度控制 | 轻量(1 个二进制 + Go) | Apache-2.0 |
| Scrapling | Python | 不支持(HTTP 抓取器) | 12/12 | 支持 | 不支持 | 中等([fetchers]) | BSD-3 |

顺带说明一下上表以及下文里出现的元数据:星标数和版本号是 2026 年 7 月初截取的,而这些数字变化很快。在把它们当成“当前状态”之前,最好去各项目的 GitHub 和包页面再核对一次。
单工具深度评测索引
这篇盘点里每个项目都有对应的深度评测:
- Crawl4AI 评测
- Firecrawl 评测
- trafilatura 评测
- Playwright vs Puppeteer 对比
- Crawlee 评测
- Scrapy 评测
- Colly 评测
- Scrapling 评测
下面是它们的封面图,另外还附上两张 JavaScript 渲染测试的真实截图,这样“8/8 动态内容”就不只是页面上的一个数字了。










任务一:把页面变成适合 LLM 使用的文本

如果你的目标是生成干净的 Markdown,喂给 RAG 流水线使用,那有三款工具在竞争,而且它们的定位差异非常大。
Crawl4AI 本质上是一个由浏览器驱动的 Markdown 生成器,只是营销话术把它包装得更复杂。顺手把搜索结果里那个“自适应智能、自学习选择器”的故事放一边吧:它并没有那种功能——那其实是另一款库的技巧(我们后面讲 Scrapling 时会提到)。它真正做的事,完成得相当不错。在 Books to Scrape 练习站上,它输出了 13,476 个字符的 Markdown;它支持 CSS schema 结构化抽取;它内置的 BFS 深度爬取在抓取一张 JavaScript 页面并截屏的同时,还沿着图谱走了 5 个页面。不过也有两个明显问题。它的原始 Markdown 会保留页面模板内容,除非你开启内容过滤;另外,那个故意返回 500 的页面,最后结果是 success=false——不是因为 Crawl4AI 优雅地识别出了 HTTP 错误,而是因为它自己的内容启发式发现错误正文太短,把它标记成了 minimal_text ... blocked。再加上安装时会把两套浏览器栈一起放进你的磁盘。当前版本 0.9.0,Apache-2.0,截至 2026 年 7 月初大约 7.1 万星。
Firecrawl 是这个组里的重量级选手,而且自托管确实能跑起来——我说“确实”,是因为那套 6 容器栈(api、playwright-service、redis、rabbitmq、nuq-postgres 和 foundationdb)真的启动成功,并且从同一个 Books to Scrape 页面产出了 9,222 个字符的 LLM-ready Markdown。它通过内置的 playwright-service 渲染了 JavaScript 页面,脚本执行后的 Einstein 引言也出现在输出里,这说明渲染是真实发生了。整个过程中我遇到的两个卡点,其实都不是 Firecrawl 本身的问题;我这里说清楚,是为了避免别人照搬错误修法:一个是源码构建时,在 colima 下碰到了 containerd snapshotter 的偶发问题(后来我改用了预构建镜像);另一个是 colima 的 198.18.x.x DNS 网段触发了 Firecrawl 的 SSRF 防护,我用 ALLOW_LOCAL_WEBHOOKS=true 解决了——这是本地开发环境的绕行方案,不是生产环境里该随便关闭的东西。自托管核心也不包含 Fire-engine,也就是云端的反爬防护层;我也没有测试云 API。更大的红旗是许可证:Firecrawl 自托管核心采用 AGPL-3.0,商业使用前必须认真做法务评估,这不是脚注。截止 2026 年 7 月初大约 14.8 万星。
trafilatura 在这一组里显得有点“反主流”,也正是很多 AI 热度榜单总会忽略它的原因。没有浏览器。没有结构化行。只有纯 Python 里又快又干净的文章文本。在文章测试样本上,它抓到了标题和 3/3 段真正正文,把模板噪音彻底剥掉——没有“登录”“订阅”或者“版权”之类的内容漏出来,而且连作者和日期也一并拿到了。在一个公开商品页上,它返回了 1,324 个字符的干净文本。它的局限也正好符合设计预期:如果你把它丢到商品目录页上,它会给你 12 个商品名称文本,但 0 行结构化数据——文本有,结构没有;它也不会渲染 JavaScript。当前版本 2.1.0,Apache-2.0,约 6.2k 星。纯文章抽取这件事上,它是我会首先想到的工具。
前面提到的两个 Markdown 字符数——Crawl4AI 的 13,476 和 Firecrawl 的 9,222——来自同一公开页面,但千万别把它们理解成质量高低差。它们反映的是不同的 Markdown 处理策略(各自保留了多少页面外壳),不是对谁更好下结论。这个数字只能作为“工具内部信号”,不是跨工具裁判,这正是前面说的规则在现实中的体现。
任务二:稳定地渲染 JavaScript

有些数据在脚本运行之前根本不会出现在 HTML 里,这时候,真正的浏览器就不再是可选项了。三款工具覆盖了这个任务,而且其中两款几乎就是同一款工具。
Playwright 和 Puppeteer 在我给它们的所有测试里都打成了平手。它们都在本地样本上渲染出了 8/8 个动态商品,在公开 Quotes JS 站点上都渲染出了 10 条内容,静态召回也都达到了 12/12,而且都能干净处理那个 500 错误(Puppeteer 会返回 response 对象,而不是直接抛错)。两者都没有自带爬取队列,所以都需要手写 BFS;在 crawl graph 上,它们都覆盖了深度 0–2 的 12 个页面。真正的差别只在于覆盖范围:Playwright 可以驱动 Chromium、Firefox 和 WebKit,并支持 Python 和 .NET;而 Puppeteer 则是 Chrome 优先、只支持 Node。这里再说明一下版本差异,因为更新速度很快:我测试的是 Playwright 1.56.0,而当前版本已经是 1.61.1,而且只测试了 Chromium;Puppeteer 测的是 24.16.0,而当前版本已到 25.3.0——你在参考时最好重新跑一遍,或者把这些差异考虑进去。两者都是 Apache-2.0,星标数分别约 9.2 万和 9.5 万。
Crawlee 是解决“队列”问题的那款工具,而这个问题正是另外两款没替你处理好的。它把 Cheerio(HTTP)引擎和 Playwright(浏览器)引擎封装在同一个 API 下面;而一个页面上的对比,基本就说明了它的卖点:Cheerio 引擎看不到任何 JavaScript 注入内容,结果是 0;Playwright 引擎在本地能看到全部 8/8,在公开站点上则是 10 条;切换引擎只需要改一行代码。它还提供真正的 RequestQueue,这也是它能归入这一类而不是第三类的原因。只是有个标题里没人会写的代价:浏览器引擎需要单独执行 npx playwright install,这会额外下载大约 80 MiB,而这部分 npm install crawlee 不会自动帮你拉下来。当前版本 3.17.0,TypeScript,Apache-2.0,约 24.6k 星。
任务三:不依赖浏览器,高速爬取
如果页面里没有 JavaScript,那浏览器往往就成了昂贵的过度方案。这里有 3 款偏 HTTP 的工具在竞争,每款代表一种语言哲学,而且它们在很多细节上都很有意思。
Scrapy 是这里工程化程度最高的框架——爬虫、JSON/CSV/XML feed 导出、AutoThrottle,该有的都有。它拿到了 12/12 的静态召回,抓到了文章的 3/3 段正文,在 crawl graph 上深度 0–2 共走了 11 个页面,并通过 handle_httpstatus_list 接住了 500。它最有意思的地方在于世界观:它不会渲染页面,而是重放请求。把它扔到 JavaScript 页面上,它拿到的是 0 个节点;但同一页面背后的 JSON API 却让它拿到了 8/8。这就是 Scrapy 的思路:找到页面真正发出的请求,然后重放它,而不是去开浏览器驱动页面。代价是依赖栈比较大(Twisted、lxml、parsel),而且我这里只测试了小样本。当前版本 2.17.0,BSD-3-Clause,约 6.3 万星。
Colly 是 Go 语言的答案,而且它对自己是什么说得非常直接:一个静态二进制文件,通过 OnHTML、OnResponse 和 OnError 回调驱动,带深度控制。它的静态召回是 12/12,通过 OnResponse 从 JSON API 拿到了 8/8,也通过 OnError 捕获了 500;在深度 2 的爬取里,它走到了 17 个页面——我会把话说得这么精确,因为这个页数是测试框架自己数出来的,不是 Colly 对“完整性”做出的保证。它不做 JavaScript:动态样本和 Quotes JS 站点都回来了 0,这是设计如此。你需要 Go 工具链来构建它,而且当前模块版本(v2.3.0)已经领先于已打标签的发布版(v2.2.0)。Apache-2.0,约 2.5 万星。
Scrapling 是这个组里的专精型工具,而且确实名副其实。它的自适应选择器可以在页面结构变化后重新找到同一个元素——所以当我把目标元素的 HTML class 从 product-name 改成 product-title 时,普通选择器匹配结果是 0,而自适应重匹配仍然把目标元素找了回来。做纯 HTTP 抽取时,它拿到了 12/12 的静态召回,在 JSON API 上也是 8/8。它自己文档里也没回避这一点:在一个合成的多元素测试里,它恢复的是 3 个中的 1 个——这说明它是“抗变化的元素追踪”,不是“全部都能自动复原”,别把它想得太神。它基础安装 pip install scrapling 还得额外加上 [fetchers] 扩展才能跑起来,而它的 StealthyFetcher 更像合规风险提示,不是适合拿到幻灯片上吹的卖点。当前版本 0.4.10,BSD-3-Clause,约 6.87 万星。
三类任务背后的共同模式
把这 9 款工具排在一起,一个很清楚的模式就出现了。对于所有偏 HTTP 的工具来说,完整静态召回——平平无奇的 12/12——只是基本盘;它们都没有在简单场景上翻车,所以这不是区分点。只有当页面里真的有 JavaScript 时,浏览器类工具额外的重量才值得;而为此它们都要付出安装成本:浏览器栈、额外安装包,或者一整套容器集群。“内置爬取队列”这一列,本质上就是框架和引擎之间的分界线——Scrapy 和 Crawlee 提供调度,而 Playwright 和 Puppeteer 则要你自己手写 BFS。整个领域的形状就是这样。没有一个工具能“总赢”,因为它们压根没在玩同一场游戏。
那么,究竟该选哪个
这套测试之所以拒绝选出总冠军,是因为真正的答案不是“哪个工具最好”,而是另一个问题——你到底在做哪一类任务?
- 需要适合 LLM 的 Markdown? 如果你要的是干净的文章文本,就选 trafilatura;如果你还希望在同一个库里同时得到 CSS 抽取和 JavaScript 渲染,就选 Crawl4AI;如果你明确需要一项自托管服务,而且能接受 AGPL-3.0 许可证和 6 容器的重量,就选 Firecrawl。
- 需要渲染 JavaScript? 要原始渲染能力,就选 Playwright 或 Puppeteer——按引擎和语言来选,因为它们本质上打平;如果你还想要现成的爬取调度,就选 Crawlee,而不是自己从零写。
- 要大规模抓取静态页面或可复现 API? Python 全功能框架选 Scrapy,单二进制、Go 语言高性能选 Colly,而如果你的痛点是页面结构经常变化、需要尽量扛住漂移,就选 Scrapling。
把工具和任务配对对了,这几款都能成立;选错类别——拿浏览器工具去抓静态页,或者拿纯 HTTP 解析器去对付 JavaScript 应用——哪怕它是全网评分最高的库,也一样会让你失望。
托管式 AI API 适合放在什么位置

上面这些工具都免费、开源,而且可以由你自己部署运行。这也正是测试里反复显现出来的共同取舍:你要自己负责浏览器环境、爬取逻辑、反爬对抗,以及所有维护成本。对很多团队来说,这种掌控力正是重点;而当你真正接手时,许可证地图也很重要——这个领域大多数工具都比较宽松(Crawl4AI、Crawlee、Playwright、Puppeteer、Colly 都是 Apache-2.0;Scrapy 和 Scrapling 是 BSD-3),只有 Firecrawl 的 AGPL-3.0 自托管核心,在商业使用前真的需要认真审查。
但也请注意,这套测试还映射出了这些工具“不做什么”。渲染、爬取、结构化和处理封锁——很少有工具能一次全包,而且还离不开你的维护。一个托管式 AI 抓取 API,可以把这一整套环节压缩成一次调用。我们在 Thunderbit 提供的开发者入口就是其中一个选择;对技术用户来说,真正重要的是 API、MCP 服务器和 CLI,而不是浏览器插件。POST /distill 返回干净的 Markdown,POST /extract 返回按 schema 定义的 JSON;JavaScript 渲染和反爬处理都在服务端完成,而不是在你的机器上本地执行。我们还为智能体和编码助手提供了官方 MCP 服务器——thunderbit_suggest_fields 可以免费用于规划抽取字段,接着 thunderbit_distill(1 credit)和 thunderbit_extract(20 credits)负责真正执行;另外还有一个 CLI,可以通过 npx @thunderbit/thunderbit-cli 在终端和定时任务里直接使用。对团队里的非开发成员,还可以使用无代码的 Chrome 扩展,而 价格页 也覆盖了这两种使用场景。
取舍其实和整篇测试所说明的是同一件事:你可以自己运行并维护最多 9 个开源库,按次调用成本几乎为零;也可以把底层设施交给别人,按请求付费。没有哪个选择是错的,关键看你愿意自己拥有多少栈。如果你更想直接看看实际提取效果,Thunderbit YouTube 频道 里有完整演示。
结论
不存在“唯一最佳”的开源网页爬虫。任何信心满满地给你一个总冠军的榜单,其实都悄悄回避了真正决定答案的问题:你到底在做哪类任务?把页面转成文本、渲染 JavaScript,还是不靠浏览器高速爬取——这个领域可以很清楚地分成这三类,而每一类里,选择又主要取决于语言和安装成本,而不是什么宇宙级冠军。
如果你只打算记住一个习惯,那就记这个:在真正投入之前,先拿自己的页面测试。这里的每一个数字都可以在基准仓库里复现,原因正是如此——因为在通用盘点里拿到第一名的工具,和能扛住你真实目标页面的工具,往往不是同一个。
试试 Thunderbit 做网页数据提取 Get Started Free
常见问题
最好的开源网页爬虫是哪一个? 没有唯一答案,得看任务。如果你要的是适合 LLM 的文本,选 trafilatura 或 Crawl4AI;如果要渲染 JavaScript,选 Playwright、Puppeteer 或 Crawlee;如果要高速 HTTP 爬取,选 Scrapy 或 Colly。在同一套测试台上,每款工具都只在自己的类别里表现最强,离开该类别后会明显变弱,所以“一刀切”排名很容易误导人。
哪些开源爬虫支持 JavaScript 渲染? Crawl4AI、Firecrawl、Playwright、Puppeteer,以及 Crawlee 的 Playwright 引擎都支持 JavaScript 渲染。Scrapy、Colly、trafilatura 和 Scrapling 的默认 HTTP 抓取方式都不支持——它们要么依赖页面背后可复现的 API(Scrapy 就是这样,它从 JSON 端点拿到了 8/8),要么需要单独启用浏览器模式。
抓网站一定要用无头浏览器吗? 只有当数据是 JavaScript 运行后才出现时才需要。如果普通 HTTP 请求加解析器就能拿到内容,那浏览器就是昂贵的过度方案——这种场景下 Scrapy、Colly 或 Scrapling 会轻得多,也快得多。
这些工具里,哪一个最适合商业用途的许可证? 大多数都比较宽松:Apache-2.0(Crawl4AI、Crawlee、Playwright、Puppeteer、Colly)或者 BSD-3-Clause(Scrapy、Scrapling)。例外是 Firecrawl 的自托管核心,它采用 AGPL-3.0,在你基于它开发商业产品之前,需要认真做许可证审查。
这些基准测试数字能复现吗? 可以。每个运行器、样本和原始结果都放在一个公开的 MIT 许可证仓库里。唯一要注意的是:召回率和结构化结果可以跨工具比较,但绝对字符数只能作为工具内部信号,因为每个工具包都是各自复刻样本,而不是共享同一份标准副本——所以请比较通过率和成功/失败,不要比较原始字符总数。


