编程 用 Scrapling 抓反爬站点:adaptive 选择器与 StealthyFetcher 的取舍

2026-08-27 20:06:09 views 7

先说结论

Scrapling(作者 D4Vinci / Karim Shoair,BSD-3,PyPI 当前 0.4.8,支持 Python 3.10–3.13,GitHub 7.6w+ star)是我近期见到的,把「站点改版后选择器失效」和「被反爬 403/429」这两件最磨人的事,用一套 API 统一掉的自适应抓取框架。

它最核心的判断是:很多抓取方案默认「网站结构不会变」,而现实是它一定会变。 Scrapling 用自适应选择器去对抗这种不确定性,而不是靠你每次手动改 selector 去补。


Fetcher 三层,怎么选

Scrapling 的抓取不是一款,而是三款,按被反爬的强度分层:

底层适用
纯 HTTPFetcherrequests/httpx 系,可伪造 TLS 指纹、支持 HTTP/3静态页,最快,10–100x 比浏览器快
浏览器DynamicFetcherPlaywright Chromium/ChromeJS 渲染 SPA、需要等网络 idle
反反爬StealthyFetcher真实 Chromium + 反指纹补丁遇到 Cloudflare Turnstile / Headless 检测

我的排序依据很简单:先用最快的,被挡再升级。 别一上来就开浏览器,那是最贵的选择。官方给的决策树也是这个思路:

  1. 静态 HTML?用 Fetcher,最快。
  2. 需要执行 JS?用 DynamicFetcher
  3. 被挡了?用 StealthyFetcher
  4. 需要跨请求保持 cookie/会话?用对应的 FetcherSession / DynamicSession / StealthySession

adaptive 选择器:这套框架的真正卖点

大多数人第一次用 Scrapling,会被 StealthyFetcher 吸引,但那只是「反反爬」这一层。真正区别于 requests + BeautifulSoup 的地方,是 adaptive 这个机制。

from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher

StealthyFetcher.adaptive = True
p = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True)

# 抓取时保存当前位置信息,站点改版后还能定位到元素
products = p.css('.product', auto_save=True)

# 等网站结构变了,再传 adaptive=True 重新定位
products = p.css('.product', adaptive=True)

它的原理,是用智能相似度算法记录元素在当前 DOM 里的「位置指纹」(包括周围结构、标签、文本特征),而不是只死记一个 .product 这个 class 名。这样当网站把 class 改掉、把层级挪了一层时,它还能靠「长得很像的那个元素」把你重新定位过去。

这是要付出代价的。 自适应不是零成本:每次 adaptive 都要跑相似度计算,比直接 .css() 慢;而且如果页面里相似元素太多,会定位到「貌似正确但其实是别的」的元素,数据就错了。所以我的建议是:

  • 初次抓取用 auto_save=True 把位置指纹存下来;
  • 等真的收到站点改版、元素抓不到报错时,再开 adaptive=True
  • 不要在每天都跑的高频任务里默认开 adaptive,除非你已经确认站点经常变。

StealthyFetcher 能过什么、不能过什么

StealthyFetcher 底层是一个打过补丁的真实 Chromium,做了几件事:

  • 自动绕过 Cloudflare Turnstile / Interstitial;
  • 处理 CDP runtime 泄漏、WebRTC 泄漏;
  • 隔离 JS 执行、抹掉部分 Playwright 指纹和 headless 特征;
  • 给 canvas 加噪,防指纹识别;
  • 提供 real_chrome=True 用本机安装的 Chrome,而不是 Chromium。

用起来很简单:

page = StealthyFetcher.fetch(
    'https://protected-site.com',
    headless=True,
    solve_cloudflare=True,   # 自动解 Turnstile
    block_webrtc=True,
    hide_canvas=True,
    proxy='http://username:password@host:port',
)

但必须说清楚边界: 它解决的是「Cloudflare 这种基于浏览器指纹 + Turnstile 的防护」,以及「Headless 特征检测」。它不是万能的。下面的情况它帮不上忙,官方文档也直接承认:

  • 验证码(CAPTCHA):官方明确「Cannot bypass」——你该做的是跳过,或走官方 API。
  • 需要登录/鉴权的接口:官方建议「Do NOT bypass——用官方 API」。强行绕过登录属于灰色地带,不值得,也容易把账号弄挂。
  • 企业级防护(Akamai、DataDome、Kasada、Incapsula):README 里 Scrapling 自己都说,这种级别它只负责 Cloudflare,更强防护要用第三方付费服务。

所以别把 StealthyFetcher 当「能扫一切」的银弹。它更适合的定位是:把你手头那些「普通反爬」的站点,从手工造指纹的泥坑里捞出来。


两点坑

1. disable_resources 能省资源,但可能让页面永远加载不完。

page = DynamicFetcher.fetch(url, disable_resources=True)

这个参数会阻断图片、字体等资源,能省流量、省代理用量,某些站点下甚至快 2x。但代价是:有的站点会因此永远不触发加载完成事件,你就卡在 network_idle 上等死。按需用,别默认开。

2. 装依赖不是一条 pip install scrapling 就完事。

抓取模式(Dynamic/Stealthy)需要浏览器,得额外跑:

pip install "scrapling[all]"
scrapling install          # 下载/安装浏览器
playwright install chromium

如果你只要纯 HTTP 层,只装 scrapling 核心包就行,省不少体积。装什么取决于你要用哪层,这个取舍值得先想清楚。


什么时候别用它

  • 你的目标站点是稳定的、纯静态、无反爬 → 直接 requests + 解析器,别引入一个带浏览器的框架,太重。
  • 你要抓的是需要登录鉴权 / 付费内容 → 别硬绕,走官方 API。
  • 你只是偶尔抓一次、没有批量 → 为了它装浏览器、学一套 API,不太划算。

Scrapling 的价值,是当你同时撞上「站点常改版 + 有反爬」这两个痛点时,用一套东西把复杂度吃掉。如果只需要其中一层的功能,用更轻的工具、或只用它的 Fetcher 层,才符合「宁可短而准」的原则。


说明:文中关于 adaptive 的性能开销、disable_resources 卡 loading 的具体表现,是基于官方文档和社区反馈整理,我未在自有环境逐站点实测。实际抓取时建议以你的目标站点为准,先小范围验证再全量跑。

复制全文 生成海报 Scrapling Web抓取 反爬 Python Cloudflare

推荐文章

程序员茄子在线接单