68K Star,一个爬虫框架凭什么统一了 HTTP、浏览器和 AI Agent

大家好,我是若风。

2025 年夏天,一个做 AI 数据采集的朋友在群里抱怨,他的爬虫项目已经攒了 6 个依赖,requests 发 HTTP,Playwright 跑浏览器,Scrapy 管调度,faker-useragent 伪造 UA,中间还夹着一个自己写的反检测脚本。每次部署环境都得折腾半天,版本兼容性更是一团乱麻。

他说,我就是想从网页上拿点数据,为什么搞得像在维护一个分布式系统?

我当时没接话,因为我也没好答案。直到上个月,我发现 Scrapling 这个项目,68,526 个 Star,6,786 个 Fork,每月 PyPI 下载量稳定增长。它做的事情很简单,把上面那一堆工具打包成一个框架,从单次 HTTP 请求到全量并发爬虫,一个库搞定。

听起来很美好。

但作为一个踩过无数开源坑的人,我第一反应不是兴奋,而是警惕。这种「全家桶」式的框架,要么是真正的一站式解决方案,要么是每层都只做 60 分的缝合怪。我花了几天时间拆它的源码,结论是,它比我想象的好,但也有一些你不会在 README 里看到的问题。

爬虫工具链的碎片化,到底有多严重

说真的,如果你没正经做过爬虫开发,你可能不太理解这个痛点。一个典型的非平凡爬虫项目,至少需要这几个组件,

  • HTTP 客户端,用来发请求,处理 TLS 指纹、Cookie 管理、重定向
  • 浏览器自动化,用来跑 JS 渲染、处理反爬验证码
  • 解析器,用来从 HTML 里提取结构化数据
  • 调度器,用来管理并发、限速、去重、暂停恢复
  • 反检测层,用来伪造浏览器指纹、绕过 Cloudflare、隐藏自动化特征

你想想看,这五个组件,每个都有各自的主流方案,而且它们之间几乎没有互操作性。你用 requests 抓的 Cookie,不能直接喂给 Playwright,你用 Scrapy 写的爬虫规则,不能复用给浏览器自动化场景。结果就是,每个新项目都在重复造胶水代码。

Scrapling 的解法是引入一个统一的会话管理层。在 scrapling/fetchers/ 目录下,它定义了三种 Fetcher,FetcherSession 对应 HTTP 请求(底层用 curl_cffi),DynamicSession 对应浏览器自动化(底层用 Playwright),StealthySession 对应反检测浏览器(底层用 Patchright,一个 Playwright 的反检测分支)。关键是,这三种 Session 共享同一套接口,同一个 Response 对象,同一个解析器。

这意味着你在 Spider 里可以这样写,

python 复制代码
class MultiSessionSpider(Spider):
    def configure_sessions(self, manager):
        manager.add("fast", FetcherSession(impersonate="chrome"))
        manager.add("stealth", AsyncStealthySession(headless=True), lazy=True)

    async def parse(self, response: Response):
        for link in response.css('a::attr(href)').getall():
            if "protected" in link:
                yield Request(link, sid="stealth")  # 路由到反检测浏览器
            else:
                yield Request(link, sid="fast")      # 路由到 HTTP 请求

同一个 Spider 里,普通页面走 HTTP 请求(快),遇到 Cloudflare 保护的页面自动切到 StealthySession(稳)。configure_sessions 里的 lazy=True 参数也很聪明,它只在真正有请求需要 stealth 通道时才启动浏览器,平时不消耗资源。

坦白讲,这个设计思路让我想起数据库的 ORM。底层可以换 MySQL、PostgreSQL、SQLite,但上层代码不感知。Scrapling 在爬虫领域做了同样的事,把「怎么获取数据」和「怎么处理数据」解耦了。

自适应元素追踪,这个特性的实现比想象中简单

Scrapling 最被吹捧的特性是「自适应抓取」,网页改版了,你的选择器还能定位到元素。

我一开始以为这背后有什么深度学习模型,结果翻源码发现,scrapling/core/storage.py 里的实现出奇地直白。它用 SQLite 存储每个元素的「指纹」,指纹由标签名、class 列表、文本内容、属性集合等特征组成,然后用 difflib.SequenceMatcher 做相似度匹配。

存储层使用了 WAL 模式(Write-Ahead Logging),scrapling/core/storage.py 第 76 行直接执行 PRAGMA journal_mode=WAL,配合 RLock 做线程安全。这意味着即使你在多线程爬虫里同时读写元素指纹,也不会锁表。

匹配逻辑在 scrapling/parser.pyfind_similar 方法里,它本质上是对候选元素逐一计算相似度分数,然后排序返回。没有机器学习,没有向量数据库,就是简单的字符串相似度加特征权重。

这反而让我更放心。太多开源项目把 AI 当营销噱头,Scrapling 没有。它的自适应能力来自工程直觉,而不是追逐热点。方法虽然简单,但在实际场景中,大部分网站改版只是改 class 名或调整 DOM 层级,文本内容和结构关系仍然稳定,SequenceMatcher 完全够用。

但这里有个细节,scrapling/core/translator.py 的 CSS 选择器转 XPath 引擎,是从 Parsel(Scrapy 的解析器)改编过来的,文件头注释里写得很清楚。Scrapling 的创新在于自适应存储和元素重定位,解析引擎本身借用了成熟方案。

Spider 引擎,一个被低估的工程细节

其实吧,Scrapling 的 Spider 引擎是我觉得最值得说的部分。不是因为功能多花哨,而是因为它的工程决策很克制。

scrapling/spiders/engine.py 里的 CrawlerEngine 类,用 anyio 做异步并发,而不是 asyncio 直接。anyio 是一个兼容 asyncio 和 trio 的抽象层,这意味着 Scrapling 的 Spider 理论上可以跑在两种异步运行时上。虽然目前文档里只展示了 asyncio 用法,但这个设计选择为未来扩展留了空间。

scrapling/spiders/checkpoint.py 的暂停恢复机制,用 pickle 序列化爬虫状态,包括待抓取队列和已访问 URL 集合,然后原子写入临时文件再替换。CheckpointManager.save 方法里先写 .tmp 文件,再 replace 到正式文件,避免写入中断导致状态损坏。这个细节说明作者真的在生产环境里用过,而不是在 IDE 里写 demo。

scrapling/spiders/robotstxt.py 的 robots.txt 解析也值得提一句。它支持 Crawl-delayRequest-rate 两种限速指令,而且会取 max(用户配置的延迟, robots.txt 要求的延迟) 作为最终延迟。这意味着你配置了 download_delay=0.5,但目标站点要求 2 秒,最终会按 2 秒执行,而不是用你的配置覆盖。

这种对规范的尊重,在爬虫框架里其实不多见。

它到底快不快,看完 benchmark 我笑了

README 里的 benchmark 表格很唬人,Scrapling 的文本提取速度是 2.02ms,碾压 BS4 的 1584ms。

但你仔细看,真相是,Scrapling 和 Parsel/Scrapy 的差距只有 2.02ms vs 2.04ms,不到 1%。那些被碾压的对手(BS4、MechanicalSoup、Selectolax)本身就是以慢著称的,选它们做对比,就像跟自行车比加速。

说真的,这个 benchmark 最大的问题不是数据造假,而是选错了参照系。它应该对比的是 Parsel(因为 Scrapling 的解析器就是基于 Parsel 改编的),而不是 BeautyfulSoup。用 BS4 做对比,只能说明 Scrapling 比 BS4 快,但这件事 lxml 十年前就做到了。

另一个 benchmark 是自适应元素查找,Scrapling 2.39ms vs AutoScraper 12.45ms。这个差距是真实的,因为 AutoScraper 用规则匹配,Scrapling 用 SQLite 存储加预处理,数据结构上的优势是实打实的。

我跑了一下 scrapling/core/storage.py 的存储逻辑,它用 sha256 做元素标识符哈希,scrapling/core/storage.py_get_hash 方法还拼接了标识符长度来降低碰撞概率。这个哈希策略在百万级元素存储时仍然能保持 O(1) 查找,确实是自适应特性的性能基础。

一些你需要知道的真相

Scrapling 是一个单人项目。

gh api 拉出来的贡献者数据显示,D4Vinci(Karim Shoair)一个人贡献了 1,450 次提交,第二名只有 10 次。27 个贡献者里,大部分是文档翻译和小的 bug 修复。这不是说单人项目不好,但 bus factor = 1 意味着,如果作者停更,这个项目就停了。

Camoufox 的前车之鉴还在那里,2025 年还很火的浏览器反检测框架,2026 年已经一年多没更新了。

另一个值得注意的点是商业化方向。README 里有 11 个 Platinum Sponsor,清一色是代理服务商(Proxidize、ColdProxy、9Proxy、BirdProxies 等)。Scrapling 的商业模式是「框架免费 + 推荐付费代理」,这和绝大多数开源项目的赞助模式不同,它直接嵌入了爬虫产业的供应链。

这本身不是坏事,但带来的影响是,Scrapling 的「反检测」能力高度依赖代理服务。StealthyFetcher 默认用 Patchright 启动 Chromium,浏览器本身就很重(几百 MB 内存起步),加上 solve_cloudflare=True 需要的额外等待时间,单次请求的延迟远高于 HTTP Fetcher。代理池的质量直接决定了你的爬虫成功率。

MCP 服务器(scrapling/core/ai.py)是另一个值得关注但还在早期的东西。它把 Scrapling 包装成 MCP 工具,让 Claude、Cursor 等 AI Agent 可以直接调用爬虫能力。想法很好,但 Issue #366 暴露了一个基础问题,遇到页面里有控制字符(U+0008),MCP 的 get 工具会直接崩溃。这个 bug 从 6 月就存在了,最新的 v0.4.10 还没修。

另外,v0.4.10 刚刚发布的 Scrapy 集成(scrapling/integrations/scrapy.py),用一个 @scrapling_response 装饰器把 Scrapy 的 Response 替换成 Scrapling 的 Response。这个功能才上线 4 天,社区反馈还很少,把它当作稳定功能还为时过早。

从 Scrapling 学到的,一个叫「统一会话层」的工程模式

拆完 Scrapling,我一直在想一个问题,它最有价值的东西到底是什么?

不是自适应解析,不是反检测浏览器,也不是 Spider 引擎。这些东西单独拿出来,都有更专业的替代品。

Scrapling 真正厉害的地方,是它设计了一个「统一会话层」。这个层的核心思想是,不同的数据获取通道(HTTP、浏览器、反检测浏览器)应该共享同一套接口,而通道的选择应该是运行时决策,不是架构时决策

我把这个模式叫作 Session Dispatcher Pattern(会话调度模式)。它的核心要素是,

  1. 所有 Fetcher 实现同一套接口(fetchgetpost),返回同一个 Response 类型
  2. 通道选择通过 sid(Session ID)在运行时动态路由,而不是在代码里硬编码
  3. 通道的创建可以是懒加载的(lazy=True),只在真正需要时初始化

这个模式不是 Scrapling 发明的,HTTP 客户端里早就有类似的抽象(比如 httpxClient vs AsyncClient),但把它应用到整个爬虫工具链,从 HTTP 到浏览器到 MCP 全部统一,Scrapling 是第一个认真做这件事的。

如果你在做爬虫项目,即使不用 Scrapling,这个模式也值得借鉴。自己写一个 SessionManager 类,封装 requestsplaywright 和反检测逻辑,统一返回你定义的 Response 协议。一开始可能觉得多此一举,但当你需要把某个请求从 HTTP 切换到浏览器模式时,改一行 sid 参数 vs 重写整个爬虫逻辑,你会感谢当初的自己。

对于 Scrapling 本身,我给出的选型建议是,适合中小型爬虫项目,尤其是需要频繁切换 HTTP 和浏览器模式的场景。如果你的项目是纯粹的 API 抓取(不需要 JS 渲染),用 httpx 就够了。如果你的项目是百万级 URL 的工业级爬虫,Scrapy 的调度和中间件生态更成熟。Scrapling 最好的位置,是中间那层,你需要灵活性,但规模还没大到需要自建调度集群。

68K Star 不是白来的,这个项目解决了真实问题。但记住,它目前是一个人在维护,而且高度依赖代理服务生态。如果你决定用它,做好被 vendor lock-in 到某个代理商的准备,或者至少把你的代理层抽象出来,别和 Scrapling 的 Session 耦合太深。

相关推荐
ZzT2 小时前
那些看不懂的 AI 味词语
aigc·openai·ai编程
树獭叔叔2 小时前
从 Search 到 Extract:AI Agent 网页工具架构拆解
后端·agent·ai编程
刘棕霆2 小时前
32—AI Skill 测评不是“跑一下”:从环境预检到 PASS 门禁的完整作战图
aigc·ai编程·测试
HjhIron2 小时前
从一问一答到自主干活:Agent 的核心设计模式 ReAct 是如何工作的
ai编程
码农胖大海2 小时前
AI 辅助学习的正确姿势和方法
人工智能·程序员·ai编程
GISer_Jing2 小时前
一套H5跑通三端:App+小程序内嵌H5跨端适配全栈解决方案
前端·前端框架·ai编程
甲维斯2 小时前
Fable5继续用!省钱50%的两个小妙招!
人工智能·ai编程
leeyi3 小时前
Go 项目怎么组织:DDD 4 层 vs MVC vs 脚本式
agent·ai编程·领域驱动设计
web_Leon3 小时前
Codex一键复刻任何网站:从安装到实战,30秒搞定原来两天的活
人工智能·ai编程