几乎每一篇“最佳开源爬虫”盘点里,都藏着一个很安静的问题:根本没人拿这些工具去跑同一批页面。Scrapy 测的是新闻文章,Playwright 测的是某个电商演示页,Colly 则是作者顺手抓来的页面——然后大家把它们硬放到一起排名,仿佛这些数字真的能互相比。这样的榜单,衡量的是页面,不是工具。
所以我做了列表里经常被省掉的那件“最无聊、也最该做”的事:搭了一套统一测试样本,把 9 款工具全部跑了一遍。样本包括:静态商品目录、JavaScript 渲染的商品目录、一篇被导航栏和页脚噪音包围的文章、一个故意返回 HTTP 500 的页面、一个小型内部链接爬取图,以及两个公开练习站点。统一的真值、统一的指标、每一次运行都一样。脚本和原始输出都放在这个公开基准仓库里: one public benchmark repo,你可以自己重新跑一遍。最后得到的,不是那些盘点文章爱承诺的整齐排行榜——没有绝对第一。这里其实对应的是三类不同任务,而这 9 款工具几乎自然地分成了三组。
这套测试台怎么搭的,以及我先说清楚的一个限制

每个工具都跑了同样的样本结构:两页共 12 个静态商品、延迟后由 JavaScript 注入的 8 个商品、包着导航栏和页脚模板但只有 3 段正文的文章、一个刻意设置的服务器 500,以及一张内部链接图。正因为设计一致,结果才能对齐——“8/8 动态商品”这句话,无论是 Puppeteer 还是 Crawlee 跑出来,意思都完全一样。
不过这里有个大多数盘点都会跳过的边界条件。每个工具的打包样本都复刻了这些 fixture,所以绝对字符数不能在工具之间直接比——它们只适合当作“同一个工具内部”的信号,不能当作跨工具评分。真正可比的,是召回率(把它当成一个比例看)、JavaScript 成败,以及结构行为。顺着这个思路还有一个范围说明:Crawl4AI 的静态目录测试只覆盖了第一页,所以它的 6/6 是在更窄范围内的满召回;而其他工具抓取了两页,所以是 12/12——这是范围更小,不是漏抓了一部分。更完整的逐个样本说明在 methodology write-up 里。
在看数字之前,还有最后一个提醒。每个工具包里也带有一个临时研究评分,但我刻意没有把它做成排名表。它们只是用来核对工具与自身证据是否匹配的内部辅助,不是联赛积分榜——如果把它们公开成总排名,就会重新制造出这次实验想避免的那种“伪精确”。这篇文章总结的是测试台的观察,不是榜单。
全场工具,一张测试台看明白
只看这张表里的两列——“Renders JS?” 和 “Built-in crawl queue”——三类任务几乎就自己跳出来了。
| 工具 | 语言 | 支持 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) | 中等(Chrome) | 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 review
- Firecrawl review
- trafilatura review
- Playwright vs Puppeteer comparison
- Crawlee review
- Scrapy review
- Colly review
- Scrapling review
下面是它们的封面图——另外还附上了两张 JavaScript 渲染测试的真实截图,这样“8/8 动态渲染”就不是纸面数字了。










任务一:把网页变成适合 LLM 的文本

如果你想要的是能直接喂给 RAG 流程的干净 Markdown,这里有三款工具在竞争,而且它们走的路线完全不一样。
Crawl4AI 本质上是一个“浏览器驱动的 Markdown 生成器”,只是营销话术把它说得更复杂。搜索结果里常跟着它出现的“adaptive intelligence self-learning selector”这种说法,其实可以先放一边:它并没有那种东西——那是另一个库的能力,等我们讲到 Scrapling 时再说。它真正做的事,做得还不错。在 Books to Scrape 练习站上,它输出了 13,476 个字符 的 Markdown,支持 CSS schema 抽取结构化内容,而且内置 BFS 深爬在爬取图样本上走了 5 个页面,同时还能渲染 JavaScript 页面并抓截图。不过它也有两个明显问题。原始 Markdown 会把页面模板垃圾一起带出来,除非你开启内容过滤;另外,那个故意返回的 500 页面最后显示 success=false,不是因为 Crawl4AI 干净利落地识别了 HTTP 错误,而是它自己的内容启发式看了那点很短的错误页面,把它标成了 minimal_text ... blocked。安装时还会在磁盘上放下两套浏览器栈。版本 0.9.0,Apache-2.0,截至 7 月上旬大约 7.1 万星。
Firecrawl 是这里的重量级选手,而且它的自托管版本确实能跑起来——我说“确实”,是因为那套 6 容器堆栈(api、playwright-service、redis、rabbitmq、nuq-postgres 和 foundationdb)真的启动成功,并且从同一个 Books to Scrape 页面产出了 9,222 个字符 的 LLM 就绪 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,在商用前必须认真做法律评估,这不是一句脚注能带过去的事。截止 7 月上旬,大约 14.8 万星。
trafilatura 是这组里最“反主流”的工具,也正是 AI 热潮榜单经常忽略的那个。没有浏览器。没有结构化表格。只有纯 Python 的快速、干净文章抽取。在文章样本上,它提取出了标题和 3/3 段正文,把模板噪音清得干干净净——没有“Login”“Subscribe”或“Copyright”之类的内容漏出来——还顺手恢复了作者和日期。面对一个公开商品页时,它返回了 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 对象,而不是直接抛错)。它们都不自带爬取队列,所以抓这张 12 页链接图时都需要手写 BFS。真正的区别只在覆盖范围: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 引擎看到了 0 个 JavaScript 注入项,Playwright 引擎在本地看到了全部 8/8(在公开站点上是 10 个),切换引擎只需要改一行代码。它还自带真正的 RequestQueue,这也是它能进入这个任务而不是第三类任务的原因。只是有个没人会写进标题里的代价:浏览器引擎需要额外执行 npx playwright install,这会再拉下约 80 MiB,而 npm install crawlee 本身并不会替你装好。版本 3.17.0,TypeScript,Apache-2.0,大约 2.46 万星。
任务三:不用浏览器也能快速爬取
页面里没有 JavaScript 时,上浏览器就是昂贵的过度方案。这里有三款以 HTTP 为先的工具竞争,分别代表不同的语言哲学,而且它们给出的答案很有意思。
Scrapy 是这组里最“工程化”的框架——蜘蛛、导出到 JSON/CSV/XML 的 feed、AutoThrottle,功能一应俱全。它在静态页上拿到了 12/12 的召回,抓到了文章的 3/3 段正文,在爬取图上从深度 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 渲染和反爬处理都在服务端完成,不用你自己机器操心。我们还有一个给 agents 和编程助手用的官方 MCP 服务器——thunderbit_suggest_fields 可以免费先规划提取字段,然后 thunderbit_distill(1 credit)和 thunderbit_extract(20 credits)负责实际执行——另外也提供一个 CLI,可以用 npx @thunderbit/thunderbit-cli 接入终端和 cron 任务。对于团队里的非开发人员,我们还提供了一个无需编码的 Chrome extension,而 pricing 页面也覆盖了这两类需求。
取舍其实和这整套测试台想说明的是同一件事:你可以自己运行并维护多达 9 个库,单次调用几乎零成本;也可以把底层工作交出去,按请求付费。两种选择都没有错,关键看你愿意自己拥有多少层技术栈。如果你更想直观看看实际提取效果,可以去看 Thunderbit YouTube channel。
{{INTERNAL_BLOG_LINKS}}
结论
没有哪个开源爬虫能被称为唯一最佳;任何自信地只给你一个答案的榜单,其实都悄悄回避了真正决定结果的问题:你到底在做哪一类任务?把网页变成文本、渲染 JavaScript,还是在不使用浏览器的情况下快速爬取——这个领域会很清楚地分成这三类,而在每一类里面,选择更多取决于语言和安装重量,而不是某个全局冠军。
如果你只从这篇文章里带走一个习惯,那就带走这一条:在真正承诺之前,先用你自己的页面测试。这里的每个数字都能在 benchmark repo 里复现,原因正是如此——因为在通用榜单里排第一的工具,和在你真实目标页上活下来的工具,往往不是同一个。
试用 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 许可证仓库里。唯一要注意的是:召回和结构结果可以跨工具比较,但绝对字符数只能在工具内部看,因为每个包都复刻了 fixture,而不是共享同一份标准样本——所以要比较比例和成败,不要比较原始字符总数。


