Colly 评测:静态 HTML、直接 JSON 与浏览器边界

最后更新于 August 17, 2026
Colly 评测:静态 HTML、直接 JSON 与浏览器边界
AI 摘要
我搭建了一个测试站点,用来验证 Colly 中那些单看页面数量或速度口碑无法回答的问题:它的回调能否提取到预期记录、是否会正确处理 HTTP 错误、能否沿着受限图谱继续爬取,以及能否读取渲染 HTML 之外传来的内容。这不是吞吐量基准测试,而是一次正确性与边界能力评估。在这些受控测试样例中,它提取出了全部预期的静态记录,将一个 500 响应交给了 OnError,并在配置的深度限制图谱中访问了 17 个 URL。对于两个只有在 JavaScript 执行后才会出现元素的页面,它返回了 0 个目标元素。

我搭了一个 fixture 测试站点,专门去验证 Colly 里那些光看页面数量或速度口碑根本回答不了的问题:它的回调能不能抓到预期记录、能不能正确处理 HTTP 错误、能不能沿着有边界的图做抓取,以及能不能拿到渲染 HTML 之外的内容。这次评估重点看的是正确性和边界,不是吞吐性能。

在这些受控 fixture 上,它提取出了全部预期的静态记录,把一个 500 响应交给了 OnError,还在配置的深度限制图里访问了 17 个 URL。对于两个只会在 JavaScript 执行后才出现的页面,它返回了 0 个目标元素。一个可以直接访问的 JSON 端点不需要浏览器也能正常用,这和渲染客户端界面是完全两回事。

Colly 到底是什么

Colly single Go binary

Colly 自称是 “适用于 Golang 的优雅爬虫和抓取框架”,这个说法其实比看上去更准确。它是一个 Go 库——GitHub 上大约有 25,300 个 star 和 1,850 个 fork——采用 Apache-2.0 许可。它不是那种下载下来就能直接输 URL 开跑的 CLI 工具。你得写 Go 代码、导入 Colly、注册几个回调,然后把整套逻辑编译成一个可执行文件。

它的工作方式是事件驱动的。你把处理器挂到 Collector 上:OnHTML 负责对匹配到的 CSS 选择器执行提取逻辑,OnResponse 直接给你原始响应体,OnError 处理请求失败。链接处理器会对发现的 URL 调用 Visit(),而 MaxDepth 用来限制遍历深度。对这些只依赖 HTTP 的路径来说,目标主机不需要另外装 Go 运行时或浏览器;最终是不是完全静态二进制,要看构建参数和 CGO 的使用情况,而这次测试并没有记录这些信息。

核心功能,以及它们在底层是怎么工作的

System diagram: Key features, and how they run under the hood

要理解 Colly,关键是先搞明白它的回调模型,因为这也是它和普通“请求 + 解析”脚本不一样的地方。我跑的每一项测试,都是靠下面这三个回调完成的。

OnHTML(selector, handler) 是最核心的工作马。把它绑定到 .productarticle p 上,Colly 在解析 DOM 时会对每个匹配元素调用你的处理器。这就是结构化提取发生的地方。它的表达方式很直接——你是在描述要抓什么,而不是自己手写一套解析循环。

OnResponse(handler) 则更底层一些,它直接把原始字节给你。当目标返回的是 JSON 而不是 HTML 时,你可以完全绕过 DOM,自己反序列化响应体。正是这个回调,让 Colly 在我的测试里处理 JSON API 时非常顺手,完全不用走 HTML 解析。

OnError(handler) 负责处理请求失败,而且可以把响应状态暴露给调用方。在这次测试里,一个状态码为 500 的 fixture 响应被送到了注册的回调中。重试、超时、DNS 失败、连接重置、回调 panic、持久化和告警都没有测试。

在这些回调之上,还有两个运行层面的特性。MaxDepth 会按 Colly 的深度语义限制链接遍历。编译后的 Go 可执行文件也意味着目标主机不需要单独安装语言运行时。这次运行没有记录构建参数或 CGO 状态,所以不能据此说每个二进制文件都是完全静态的。

环境搭建:需要 Go 工具链

依赖不多,但确实存在,所以在你安装任何东西之前先说清楚。我测试的机器上没装 Go,而 Colly 又是一个 Go 库——所以第一步就是先把 Go 工具链装上(我通过 Homebrew 安装了 Go 1.26.5)。如果你的团队本来就不在 Go 生态里,真正的门槛就在这里:不是 Colly 本身,而是它在编译任何一行代码前所需要的语言环境。

装好 Go 之后,go get github.com/gocolly/colly/v2 解析到了 v2.3.0。测试路径不需要浏览器,也不需要 headless Chrome。

这里有一个版本层面的细节很容易让人搞混。Go 模块解析到的是 v2.3.0(发布于 2025 年 12 月),而我检查时 GitHub Releases 页面能看到的最新条目是 v2.2.0(2025 年 3 月)。这里的差别是模块/仓库版本和 GitHub Release 条目之间的差异,不是模块和 Git 标签之间的差异。我测试的是 v2.3.0

实测:提取能力与运行边界

Colly static and JSON results

我把 Colly 跑在一个自包含的 fixture 服务(Go 的 httptest)以及两个公开演示站点上。当前的 benchmark 目录results/colly-test-summary.json 提供了相关产物,但这两个链接都指向会变化的分支。文章没有给出已测试的 commit、精确命令、构建参数或 fixture seed,因此它还算不上是一份不可变的复现说明。

测试目标结果
静态目录 + 分页本地 fixture提取到 12/12 个预期商品
文章提取本地 fixture标题 + 3/3 段落
直接 JSON 响应本地 fixture通过 OnResponse 获取 8/8 个预期条目
HTTP 500 处理本地 fixture路由到 OnError,状态码 500
抓取图(MaxDepth 2)本地 fixture17 个页面
Books to Scrape公开演示站点20 个商品
动态页面(不执行 JS)本地 fixture0 个卡片(符合预期)
Quotes JS(未渲染)公开演示站点0(符合预期)

在这些受控的静态 fixture 上,配置好的选择器拿到了 12/12 个预期商品记录,以及全部 3 段预期文章段落。直接 JSON 响应从头到尾都没有碰到 HTML 解析器:OnResponse 提供了响应体,测试框架自己解码出了全部 8 个预期条目。那个唯一的 500 fixture 被送到了 OnError,状态码也被暴露出来,这次运行没有因此崩掉;但这并不等于它已经证明了无人值守的稳定性。在公开的 Books to Scrape 页面上,选择器返回了 20 个商品,算是一次公开站点的冒烟测试。

在遍历方面,采集器按照测试框架的 seed-depth 约定设置为 MaxDepth(2),并在 fixture 图中访问了 17 个 URL。这个结果反映的是爬取覆盖率,不是速度。观察到的轨迹——而不是对任意图结构的泛化结论——记录在 results/local_crawl_graph.json 中。

Colly JavaScript zero result

Colly 不会执行 JavaScript。这个由 JS 渲染的 fixture 返回了 0 个目标卡片,而公开的 Quotes to Scrape JS 页面 也返回了 0 个目标 quotes。如果某些元素只有在浏览器执行后才会出现,而又没有可直接访问的后端端点提供这些数据,那么只靠 HTTP 的路径就看不到这些已渲染的 DOM。要么接入渲染器,要么在存在可用端点时直接调用后端接口,就像这个 JSON fixture 展示的那样。

我没有测试异步采集器、限速或礼貌访问配置、代理轮换、重试机制,也没有测试队列和存储后端。没有测量耗时、吞吐量、并发、CPU、内存、目标延迟或对照基线。因此,这篇文章并不声称速度或无人值守可靠性。

如何解读这些 fixture 结果

这三条成功的数据路径,其实是在测试三种不同的契约。目录页和文章页测试的是对服务器返回 HTML 的 CSS 选择能力。它们的分母是提取前就写好的 fixture 预期:12 条商品记录和 3 段文章内容。把结果写成“提取到预期记录”是有意为之。这次运行没有定义模糊匹配、重复项处理、部分字段容忍度,也没有定义整个语料库层面的召回率指标,所以这个结果不应该被夸大成通用的提取准确率。

JSON 场景绕过了 DOM 选择。Colly 通过 OnResponse 接收响应字节,然后由测试框架完成 JSON 解码。所以“Colly 不执行 JavaScript”并不代表所有依赖客户端的站点都完全不能用。如果客户端用的数据源是一个可直接调用的端点,而且这个请求能在浏览器外复现,那么 HTTP 爬虫还是可能够用。认证、动态签名、仅浏览器态状态和反爬机制都会改变答案;这次测试都没覆盖。

那个 500 路由测试验证的是分发,不是恢复。它说明注册的 OnError 回调确实收到了该 fixture 响应及其状态码。生产级爬虫仍然需要针对可重试状态码、退避策略、终止性失败、持久化和告警制定明确策略。这次测试不能证明这些能力,“回调被触发了”也不该被理解成“这个任务可以放心无人值守”。

Colly depth-2 crawl graph

这个 17 URL 的图同样只说明一个很窄的范围。它确认的是在这个 fixture、这个 seed 约定和 MaxDepth(2) 下得到的访问集合。它并不能证明每秒页面数、跨主机公平性、内存增长情况,或者在循环和重复 URL 形式下的行为。这些都需要单独的工作负载和队列测试。

基于这次运行的选型清单

先看 Colly 实际收到的响应是什么。如果所需字段已经存在于服务器返回的 HTML 里,就用 OnHTML,并在接受记录前验证字段数量或必需键。如果响应是 JSON,就通过 OnResponse 处理正文并校验 schema。如果 HTML 只是一个应用壳,先检查是否有可访问的后端请求包含这些数据,再考虑加浏览器。

响应中包含什么Colly 路径验收检查
服务器返回 HTML 中的必需字段OnHTML 选择器必需键和预期记录数量
可直接调用的 JSON 载荷OnResponse + JSON 解码schema 与必需字段校验
由可复现请求支持的 HTML 壳请求后端端点响应状态、schema 和完整性
只有浏览器执行后才生成的数据添加渲染器或改用浏览器爬虫针对目标的就绪性和完整性

当必须依赖浏览器执行时,要把它当成另一个组件,而不是指望 Colly 的某个参数就能直接开启渲染。浏览器必须负责判断就绪、暴露渲染后的内容或后端响应,并把数据交给流水线的其他部分。这次评测没有测试这样的集成。

在部署时,建议记录 Go 版本、模块版本、构建参数、CGO 状态、精确命令、fixture seed 和仓库 commit。当前公开链接里缺少这些信息,而它们恰恰决定了结果到底是可检查的产物,还是一份能长期复现的说明。运维层面则应补上失败矩阵,并在调用系统“快”或“稳”之前,先测量你真正关心的工作负载。

优点与缺点

优点:

  • 通过 OnHTML 成功提取了 12/12 个预期目录商品和 3/3 段预期文章内容。
  • 通过 OnResponse 可以干净地处理 JSON,无需 DOM 解析——API 条目 8/8。
  • 测试中的 500 响应成功进入 OnError,并暴露了状态码。
  • 单个采集器就能完成深度限制抓取,覆盖 17 个页面。
  • 可编译为 Go 可执行文件;对测试路径来说,目标主机不需要单独安装 Go 运行时。
  • Apache-2.0 许可比较宽松。

缺点:

  • 不执行 JavaScript——客户端渲染内容直接返回 0,没有例外。
  • 需要 Go 工具链;非 Go 团队在写任何爬虫之前都要先承担这部分环境搭建成本。
  • 测试所用模块(v2.3.0)领先于当前观察到的最新 GitHub Release 条目(v2.2.0)。
  • 输出完全由你自己的代码负责——Colly 提供的是回调,不像 Scrapy 那样自带数据集/Feed 导出器。
  • 异步、限速、代理和队列后端虽然存在,但这里都没测;吞吐和规模表现仍然没量化。

适合谁,不适合谁

Colly no-browser boundary

如果你本来就写 Go,而且目标是服务器渲染 HTML 或可直接访问的 JSON,那么 Colly 很合适。它的回调模型把结构化匹配、原始负载和请求失败分得很清楚。编译后的可执行文件也避免了目标机器上单独安装语言环境的麻烦,不过这次没有验证完全静态链接。

如果目标元素只有浏览器执行后才出现,并且没有可用的后端端点,那就需要加渲染器。反过来,如果有可直接访问的 JSON 端点,还是可以不依赖渲染直接请求。对于不想维护 Go 工具链、或者希望由提取服务来承担 schema 整理和选择器维护的团队来说,Colly 也不是特别合适。

替代方案,以及 Thunderbit 适合放在哪

Colly 是你自己运行的开源软件。它没有厂商使用费,但计算资源、带宽、代理、存储、可观测性和工程投入都得你自己扛。请求行为、解析回调、抓取逻辑,以及如果目标需要渲染时的浏览器集成都由你负责。

托管式提取服务可以把其中一部分责任交给供应商。我们在做 Thunderbit,但这次没有拿它和这些 fixture 做对比,所以本文不对渲染、反爬、质量、延迟或成本做任何比较。能明确区分的是责任归属:Colly 在你的 Go 进程里暴露 HTTP 响应和回调;托管服务则可以按次调用收费,代你完成采集和 schema 整理。

相关的基准评测还有:开源爬虫完整对比Scrapy Python 爬虫评测Scrapling 自适应选择器评测

试用 Thunderbit 进行网页数据提取

结论

对于使用 Go、目标是服务器渲染 HTML 或直接 JSON、并且愿意自己维护提取代码的团队来说,Colly 是一个很有竞争力的选择。这些 fixture 证明了它能提取预期记录、跑出一条有边界的爬取轨迹,并正确触发一个 500 回调——但没有证明速度、规模或无人值守可靠性。如果页面内容需要浏览器渲染,除非底层数据端点可以直接调用,否则就得走另一条路。

试用 Thunderbit 进行网页数据提取 Get Started Free

常见问题

这次评测测了 Colly 的速度吗? 没有。它测的是预期记录提取、直接 JSON 处理、一个错误回调,以及对一个 fixture 抓取图的覆盖情况。没有测耗时、吞吐量、并发、CPU、内存或对照基线。

Colly 能抓 JavaScript 渲染页面吗? Colly 不会执行页面里的 JavaScript。所以,这次测试中的 HTTP 路径看不到那些只在渲染后的 DOM 里出现的目标元素。不过,如果存在可直接访问的后端 JSON 端点,它仍然可以直接请求,如 JSON fixture 所示。若必须依赖执行后的结果,而且没有可复现的后端请求,就要使用渲染器。

使用 Colly 需要懂 Go 吗? 需要。Colly 是一个 Go 库,不是独立 CLI——你需要导入它、注册回调(OnHTMLOnResponseOnError),然后编译。我测试的机器上没装 Go,所以第一步就是先安装 Go 工具链(1.26.5)。如果你的团队本来就不在 Go 里,这套环境才是真正的安装成本。

为什么我安装到的版本和 Colly 最新 GitHub Release 对不上? Go 模块解析到的是 v2.3.0(2025 年 12 月),而我观察到的最新 GitHub Release 条目是 v2.2.0(2025 年 3 月)。我测试的是 v2.3.0;这只是不同版本展示层之间的差异,不代表安装有问题。

Colly 可以免费用于商业用途吗? 可以,它采用 Apache-2.0 许可,比较宽松,也适合商业使用。不过,正式使用前还是建议再确认一下 仓库 上的最新许可证信息。

在生产环境采用之前,建议补充和实际风险匹配的测试,而不是只靠 fixture 结果做类比外推。对代表性目标做重复爬取计时,记录 CPU 和峰值内存,演练可重试失败和终止性失败,并在并发场景下验证礼貌访问。如果需要持久化,就在检查重复处理和队列状态的同时暂停并恢复一次爬取。如果部署简化很重要,就记录精确的编译器和链接器配置,并检查生成二进制的运行时依赖。以上检查都不会改变当前 fixture 已经证明了什么;它们决定的是,这个库配置是否适合某个具体的生产任务。

Ke
Ke
Thunderbit 首席技术官 | 高级数据科学家与机器学习专家 Ke Shen 拥有近十年的机器学习和数据科学经验,毕业于哥伦比亚大学,曾任 Walmart Labs 高级数据科学家。他在 Python、R、Java 和统计学方面拥有深厚且备受同行认可的专业能力,并分享如何将复杂的 AI 算法从理论落地到生产级架构的实战经验。
目录
Thunderbit · AI 网页数据代理

一键 内提取任意页面数据

深受 250,000+ 用户信赖
提供免费方案
从网页到表格
描述你的需求——Thunderbit 的 AI 代理会帮你抓取并导出到 Excel、Google Sheets、Airtable 或 Notion。可免费开始。
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week