Scrapling:让爬虫在现代 Web 里“活下来”的自适应抓取框架

面向动态页面、反爬机制、结构频繁变化和 AI 数据抽取场景的一体化 Python Web Scraping 技术介绍。
在这里插入图片描述

目录

一句话认识 Scrapling

Scrapling 是一个面向现代 Web 的自适应爬虫框架:它既可以像传统解析库一样处理 HTML,也可以通过 HTTP、浏览器自动化、隐身浏览器、代理轮换和 Spider 框架完成从单页请求到大规模并发爬取的完整流程。

官方文档对它的定位很直接:Scrapling 是一个 adaptive Web Scraping framework,覆盖从单次请求到 full-scale crawl 的场景;它的解析器可以学习页面变化,在页面更新后重新定位元素;它的 fetcher 体系还能处理动态页面和部分反爬保护。

换句话说,Scrapling 不是“又一个 HTML 解析器”,而是试图把下面几件事放进同一个工程体验里:

能力 传统做法 Scrapling 的思路
静态页面抓取 requests + 解析库 Fetcher 返回可直接查询的 Response
动态页面抓取 Playwright / Selenium 脚本 DynamicFetcher 封装浏览器加载与解析
复杂反爬页面 自行调浏览器指纹、代理、等待策略 StealthyFetcher + 会话 + 代理能力
页面结构变化 手工改 CSS/XPath adaptive=True 进行元素相似度恢复
多页面爬取 自建队列、并发、状态管理 Scrapy-like Spider 框架
AI 数据抽取 整页丢给模型,成本高且噪声大 MCP 工具先定位内容,再把目标片段交给 AI

它解决的核心问题

现代网页抓取最难的地方往往不是“发请求”,而是请求之后的一整串工程问题。

第一,页面越来越动态。 很多数据不在初始 HTML 中,而是由 JavaScript 渲染、XHR/fetch 请求或客户端状态拼装出来。只用 HTTP 请求会很快撞墙。

第二,反爬系统越来越常见。 TLS 指纹、浏览器头、Cloudflare Turnstile、浏览器自动化痕迹、代理质量、DNS 泄漏和广告追踪请求都会影响稳定性。

第三,选择器脆弱。 传统 .product > div:nth-child(2) > span.price 这种选择器很容易在页面改版后失效,维护成本随站点数量线性上升。

第四,爬虫从脚本变成系统后,复杂度陡增。 并发、限速、会话复用、失败重试、断点续跑、robots.txt、导出格式、统计指标和开发期缓存都需要统一处理。

Scrapling 的价值就在于:它不是只补一个点,而是把“获取页面、解析页面、适应变化、组织爬取、服务 AI”做成一条相对完整的链路。

总体架构

Scrapling 可以理解为五层能力的组合:

  1. Fetcher 层:负责拿到页面,包括静态 HTTP、动态浏览器和隐身浏览器。
  2. Response / Selector 层:负责 DOM 查询、文本提取、属性读取和导航。
  3. Adaptive 层:负责保存元素特征,并在选择器失效后用相似度重新定位。
  4. Spider 层:负责多页面爬取、请求调度、并发、暂停恢复、导出和统计。
  5. CLI / MCP / AI 集成层:让抓取能力可以被终端、交互 shell 或 AI Agent 调用。

静态页面

JS 渲染

强保护 / 反爬

目标 URL

页面类型

Fetcher

DynamicFetcher

StealthyFetcher

Response / Selector

CSS / XPath / Text / Regex 查询

Adaptive 元素恢复

结构化数据

JSON / JSONL / Pipeline / AI MCP

这套架构的关键不是“所有场景都用浏览器”,而是按成本分层:能用快速 HTTP 就不要启动浏览器;必须跑 JS 时再进入浏览器;遇到更强反爬时才使用更重的隐身抓取。

抓取层:三种 Fetcher 的分工

在这里插入图片描述

Scrapling 的官方文档把 fetcher 定义为“单行完成请求或页面获取,并返回 Response 对象”的类。它目前提供三类主要抓取器,每类都有自己的适用边界。

Fetcher 适合场景 技术重点 成本
Fetcher 静态页面、接口返回 HTML、基础抓取 HTTP 请求、浏览器指纹模拟、Headers、HTTP/3 等 最低
DynamicFetcher 需要 JavaScript 渲染的页面 Playwright 驱动 Chromium / Chrome 中等
StealthyFetcher 反爬强、需要更真实浏览器行为的页面 隐身浏览器、指纹伪装、Cloudflare 等保护处理 最高

一个典型使用方式如下:

from scrapling.fetchers import Fetcher, StealthyFetcher, DynamicFetcher

# 轻量 HTTP 抓取
page = Fetcher.get("https://example.com")
print(page.status)
print(page.css("h1::text").get())

# 动态页面或需要等待网络空闲的页面
page = DynamicFetcher.fetch(
    "https://example.com/app",
    headless=True,
    network_idle=True,
)

# 需要更强反爬处理时
page = StealthyFetcher.fetch(
    "https://example.com/protected",
    headless=True,
    network_idle=True,
)

会话能力

从工程视角看,会话能力比“单次请求”更重要。Scrapling 为不同抓取器提供 session 类,用来复用 Cookie、浏览器上下文和状态,避免每个 URL 都从零启动。对于登录后抓取、分页抓取、购物车态页面、带地区状态的网站,这类会话复用能显著降低失败率和资源消耗。

代理与请求控制

Scrapling 的 Spider 和 Fetcher 体系支持代理轮换、每次请求代理覆盖、阻塞检测、重试、域名过滤和广告/追踪域名阻断。对于浏览器型抓取器,阻断广告与追踪请求还有一个额外价值:页面更快,传给 AI 或下游清洗逻辑的噪声更少。

解析层:像 Scrapy 一样熟悉,但更耐变

Scrapling 的 Response 对象继承了选择器式体验:你可以用 CSS、XPath、文本搜索、正则搜索等方式定位元素。它的风格接近 Scrapy / Parsel,因此对爬虫开发者比较友好。

from scrapling.fetchers import Fetcher

page = Fetcher.get("https://quotes.toscrape.com")

for quote in page.css("div.quote"):
    item = {
        "text": quote.css("span.text::text").get(""),
        "author": quote.css("small.author::text").get(""),
        "tags": quote.css(".tags a.tag::text").getall(),
    }
    print(item)

Response 不只是 DOM,它还保留了响应元信息:

  • status:HTTP 状态码
  • headers:响应头
  • cookies:响应 Cookie
  • history:重定向历史
  • body:原始响应体
  • encoding:编码信息
  • meta:Spider 与代理等上下文信息
  • captured_xhr:启用浏览器 XHR 捕获时的请求结果

这意味着你不需要在“请求对象”和“解析对象”之间来回转换,抓取和提取可以保持在同一个上下文里。

自适应抓取:网站改版后的元素恢复

在这里插入图片描述

Scrapling 最有辨识度的能力是 Adaptive Scraping。它的目标很明确:当网页结构变化、原 CSS/XPath 选择器失效时,仍然尽可能找到“同一个业务元素”。

传统选择器通常依赖固定结构:

element = page.css("#p1")

如果网站把 id="p1" 改成 data-id="p1",或把元素包进新的容器,选择器就可能失效。Scrapling 的 adaptive 机制会先保存元素的特征,后续再通过相似度匹配找回它。

官方文档把这个过程分为两个阶段:

  1. Save Phase:保存目标元素的唯一性特征。
  2. Match Phase:页面结构变化后,用保存的特征在新 DOM 中寻找最相似元素。

保存的特征包括但不限于:

  • 元素标签名
  • 文本
  • 属性名与属性值
  • 兄弟元素标签
  • 路径上的标签信息
  • 父元素标签、属性和文本

CSS / XPath 方式

from scrapling import Fetcher

Fetcher.configure(adaptive=True)

page = Fetcher.get("https://example.com")

# 第一次命中时保存元素特征
product = page.css(".product-card", auto_save=True)

# 未来页面结构变化后,用 adaptive 尝试恢复
product = page.css(".product-card", adaptive=True)

手动保存与恢复

对于不是通过 CSS/XPath 找到的元素,也可以手动保存和恢复:

element = page.find_by_text("Tipping the Velvet", first_match=True)

page.save(element, "book_title_link")

saved = page.retrieve("book_title_link")
matches = page.relocate(saved, selector_type=True)

这类能力很适合长期运行的采集任务,尤其是目标站点会频繁改类名、重排 DOM 或进行 A/B 测试时。

注意:自适应不是魔法。它依赖历史保存数据和相似度判断。如果目标元素的文本、父级上下文、属性和位置关系都发生剧烈变化,仍然需要人工介入或重新保存特征。

Spider 框架:从单页脚本走向规模化爬取

Scrapling 的 Spider API 与 Scrapy 思路接近:定义 namestart_urls 和异步 parse() 方法,在回调里产出数据或后续请求。

from scrapling.spiders import Spider, Response


class QuotesSpider(Spider):
    name = "quotes"
    start_urls = ["https://quotes.toscrape.com"]

    async def parse(self, response: Response):
        for quote in response.css("div.quote"):
            yield {
                "text": quote.css("span.text::text").get(""),
                "author": quote.css("small.author::text").get(""),
            }

        next_page = response.css("li.next a::attr(href)").get()
        if next_page:
            yield response.follow(next_page, callback=self.parse)


result = QuotesSpider().start()
print(result.stats.items_scraped)

相比单文件脚本,Spider 系统提供了更适合生产任务的能力:

能力 说明
并发爬取 可配置并发、下载延迟、域名级节流
多 Session HTTP、动态浏览器、隐身浏览器可以在同一个 Spider 内按 session 路由
暂停与恢复 基于 checkpoint 的持久化,适合长任务
流式输出 可以边抓边消费结果,适合 UI、数据管道和长时间任务
阻塞检测 支持对被拦截请求进行检测与重试
robots.txt 可选遵守 DisallowCrawl-delayRequest-rate
开发模式 缓存响应并回放,调试解析逻辑时避免重复请求目标站
内置导出 支持 JSON / JSONL 等常见结果形式

请求跟随

response.follow() 会自动处理相对链接,并默认设置 Referer,这让分页、详情页、列表页递归抓取更自然:

async def parse(self, response: Response):
    for href in response.css("a.product-link::attr(href)").getall():
        yield response.follow(href, callback=self.parse_product)

async def parse_product(self, response: Response):
    yield {
        "name": response.css("h1::text").get(""),
        "price": response.css(".price::text").get(""),
    }

AI 与 MCP:把网页清洗后再交给大模型

Scrapling 还提供 MCP Server,让 AI Agent 可以通过工具调用完成网页抓取、动态页面获取、隐身抓取、截图、会话管理和内容抽取。

这部分的重点不是“让 AI 自己浏览网页”,而是让 AI 使用 Scrapling 的确定性抓取能力:

  1. 先用 CSS 选择器、文本或结构定位目标区域。
  2. 再把目标片段转换成 Markdown、HTML 或干净文本。
  3. 最后把精简后的内容交给模型处理。

这种方式有两个明显好处:

  • 降低 token 成本:不用把整页 HTML 或大量无关文本交给模型。
  • 提升数据质量:选择器先做结构约束,模型只处理相关内容。

MCP Server 提供的能力包括 HTTP 抓取、动态内容抓取、隐身抓取、批量抓取、截图、持久浏览器会话、代理支持和提示注入防护。对于“让 Agent 帮我从网页里抽表格、价格、规格、文章主体”的场景,它比裸浏览器更可控。

安装与快速上手

Scrapling 要求 Python 3.10 或更高版本。

基础安装

pip install scrapling

基础安装主要包含解析引擎和核心依赖,不包含 fetcher 与命令行扩展。

使用 Fetcher / 浏览器能力

pip install "scrapling[fetchers]"
scrapling install

scrapling install 会安装浏览器及相关依赖。

AI / MCP 功能

pip install "scrapling[ai]"

Shell 与 extract 命令

pip install "scrapling[shell]"

全量安装

pip install "scrapling[all]"
scrapling install

Docker

docker pull pyd4vinci/scrapling

# 或 GitHub Container Registry
docker pull ghcr.io/d4vinci/scrapling:latest

适用场景与选型建议

很适合 Scrapling 的场景

  • 页面结构会频繁变化,需要降低选择器维护成本。
  • 既有静态页面,也有动态页面,希望统一抓取接口。
  • 需要从少量脚本逐步演进为并发爬虫。
  • 需要会话、代理、限速、暂停恢复和导出能力。
  • 需要把网页内容稳定地交给 AI Agent 或 MCP 工具链。
  • 团队熟悉 Scrapy / BeautifulSoup,希望保留类似查询体验。

不一定需要 Scrapling 的场景

  • 只抓一个稳定接口,直接请求 JSON 即可。
  • 只做一次性页面抓取,维护性不重要。
  • 所有数据都来自官方 API,且 API 已经足够稳定。
  • 对浏览器自动化有强定制需求,并且团队已经有成熟 Playwright 基础设施。

Fetcher 选择指南

目标页面情况 推荐选择
HTML 已包含目标内容 Fetcher
数据由 JavaScript 渲染 DynamicFetcher
需要保持 Cookie / 登录态 对应 Session 类
Cloudflare / 自动化检测明显 StealthyFetcher
大规模列表页与详情页 Spider
目标会频繁改版 adaptive=True + auto_save=True
需要 AI 辅助抽取 MCP Server + 精准选择器

工程实践建议

1. 先低成本,后高能力

不要一上来就用浏览器。可以按这个顺序试:

  1. Fetcher:确认静态 HTML 是否足够。
  2. DynamicFetcher:确认是否必须执行 JS。
  3. StealthyFetcher:只有遇到明显反爬时再升级。

这样能控制资源消耗,也能让系统更容易扩容。

2. 给关键字段启用 adaptive

不是所有元素都需要自适应。建议优先保护这些字段:

  • 商品标题、价格、库存、SKU
  • 文章标题、正文、发布时间、作者
  • 搜索结果项、分页按钮、详情页链接
  • 登录后页面里的关键操作按钮

对于这些字段,可以在首次稳定命中时 auto_save=True,后续任务中再启用 adaptive=True

3. 选择器要表达业务含义

即使有自适应,也不要依赖过深的 nth-child。更稳的策略是组合业务上下文:

# 脆弱:结构稍变就失效
price = item.css("div:nth-child(3) > span:nth-child(2)::text").get()

# 更稳:用语义类名、文本或局部上下文
price = item.css(".price::text").get("")

4. 把抓取层和抽取层分开

生产环境里建议把代码分成两类:

  • 获取页面:URL、Fetcher 类型、代理、等待策略、会话。
  • 解析页面:选择器、字段清洗、结构化输出。

这样当目标站点从静态变成动态时,只需要替换 Fetcher,不必重写解析逻辑。

5. 为长任务开启可恢复机制

大规模爬取时,断点续跑比“跑得快”更重要。Spider 的 checkpoint、开发模式缓存、流式输出和统计信息可以帮助你把爬虫从脚本推进到可运维任务。

6. AI 场景不要整页喂模型

如果使用 MCP 或 AI Agent,优先用 Scrapling 定位内容,再交给模型总结、转换或分类。让确定性工具做确定性筛选,让模型做语义处理,这是更稳的组合。

小结

Scrapling 的核心吸引力在于它抓住了现代爬虫的真实痛点:页面动态化、反爬常态化、DOM 不稳定、任务规模化,以及 AI 抽取对干净上下文的需求。

它的技术路线可以概括为:

用分层 Fetcher 获取页面,用熟悉的 Selector 抽取数据,用 Adaptive Scraping 对抗结构变化,用 Spider 框架承载规模化任务,再用 MCP 把能力交给 AI 工具链。

如果你的爬虫只是一次性脚本,Scrapling 可能显得有点“全”。但如果你正在维护一批长期运行、页面经常变化、还要兼顾动态渲染和反爬处理的数据采集任务,它提供的是一条从脚本到框架、从人工维护到自适应恢复的升级路径。

参考资料

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐