首页
/ Scrapling 自适应 Web 爬虫框架:从单请求到大规模爬取的完整技术指南

Scrapling 自适应 Web 爬虫框架:从单请求到大规模爬取的完整技术指南

2026-09-04 21:29:49作者:鲍丁臣Ursa

本文基于 Scrapling 仓库中的官方 README(西班牙语版 docs/README_ES.md)撰写,系统讲解这套“自适应 Web 抓取框架”的三大核心——自适应解析器(Parser)、多引擎抓取器(Fetchers)与并发爬虫框架(Spiders),并结合仓库源码逐一印证其特性、安装方式、命令行工具与性能基准。读完后,你将能够独立完成安装配置、选择合适 Fetcher 发起请求、编写支持断点续爬的 Spider,以及使用 CLI 零代码提取页面内容。

Scrapling Spider 框架架构图

Scrapling 官方定位是:“一个自适应的 Web 抓取框架,能够处理从单个请求到大规模爬取的一切(An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl)”。其两大核心卖点在 README 开篇即有明确表述:

  1. 解析器会“学习”网站变化:当页面结构更新后,能够自动重新定位(relocate)你之前保存的元素;
  2. Fetcher 原生具备反爬规避能力:可以直接处理 Cloudflare Turnstile/Interstitial 等反机器人系统;
  3. Spider 框架支持并发、多会话、Pause & Resume 与自动 Proxy 轮换,全部只用少量 Python 代码完成。

仓库中一段最精炼的入门代码即展示了“抓取 + 自适应解析”的主线用法(继承自 README):

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)   # 提取能“存活”于站点改版的数据
products = p.css('.product', adaptive=True)   # 站点结构变化后,传 adaptive=True 即可重新找到元素

核心特性总览

README(docs/README_ES.md)将特性划分为五大板块:Spiders 爬虫框架、高级 Fetch 能力(含 Session)、自适应抓取与 AI 集成、高性能架构、以及开发者体验。下面逐一展开,并给出仓库中的实现位置作为佐证。

Spiders:完整的 Scrapy 风格爬取框架

官方特性列表包括(以下条目均出自 README,路径已转换为仓库相对路径以便查证):

  • Scrapy 风格 API:用 start_urls、异步 parse 回调、Request/Response 对象定义 Spider,实现位于 scrapling/spiders/spider.py
  • 并发爬取:可配置并发上限、按域限速与下载延迟(对应 scrapling/spiders/throttle.py);
  • 多会话(Multi-Session):在同一个 Spider 中统一使用 HTTP 请求与隐身浏览器会话,按会话 ID 路由请求到不同 Session;
  • Pause & Resume:基于 Checkpoint 的爬取持久化,按 Ctrl+C 可优雅停机,再次启动时从上次进度继续。源码中 Spider.__init__ 接受 crawldir 参数,注释明确写着 “Directory for checkpoint files. If provided, enables pause/resume”(见 scrapling/spiders/spider.py#L106-L138);
  • 流式模式(Streaming):通过 async for item in spider.stream() 在元素产生时即时消费,并附带实时统计,适合 UI、管道与长时爬取;
  • 被拦截请求检测:自动检测被拦截的请求并重试,重试逻辑可自定义;
  • AutoThrottle:Spider 根据站点响应速度自动调整每个域的延迟,被限流/拦截时自动加倍延迟(或遵循 Retry-After 响应头),恢复后再加速;
  • robots.txt 合规:可选 robots_txt_obey 标志,尊重 DisallowCrawl-delayRequest-rate 指令并按域缓存(实现见 scrapling/spiders/robotstxt.py);
  • 开发模式:首次运行时把响应落盘,后续运行直接回放,让你反复调试 parse() 逻辑而不必反复访问目标服务器;
  • 即用型 Spider 模板CrawlSpider(按规则追链)、SitemapSpider(sitemap/robots 引导式爬取)、XMLFeedSpider/CSVFeedSpider(迭代 XML/RSS 与 CSV 源)、ShopifySpider(通过 Shopify JSON API 按变体粒度导出全部商品)。这些模板分别实现在 scrapling/spiders/templates/crawler.pyscrapling/spiders/templates/sitemap.pyscrapling/spiders/templates/feed.pyscrapling/spiders/templates/shopify.py,并从 scrapling/spiders/init.py 统一导出;
  • 链接提取原语:独立的 LinkExtractor,支持 allow/deny 模式、域名过滤、CSS/XPath 边界、扩展名过滤与规范化(实现见 scrapling/spiders/links.py);
  • 结果导出:除自带 hook/管道外,还提供内置导出方法。源码 scrapling/spiders/result.py 中可以看到 ItemsResult 的四个导出方法签名:to_json(path, *, indent=False)to_jsonl(path)to_csv(path, *, fields=None, delimiter=",")to_xml(path, *, root_tag="items", item_tag="item", indent=True)

高级 Fetch 能力与 Session 体系

README 列出的高级抓取能力包括:

  • HTTP 请求Fetcher 提供快速的 HTTP 请求,可模仿浏览器 TLS 指纹、自定义请求头,并支持 HTTP/3;
  • 动态加载DynamicFetcher 基于 Playwright 的 Chromium/Chrome 提供完整浏览器自动化;
  • 反爬规避StealthyFetcher 具备更深入的隐身能力与指纹伪造,可自动处理各类 Cloudflare Turnstile/Interstitial 质询。在 scrapling/fetchers/stealth_chrome.py 的参数文档中可以看到:network_idle 表示“等待页面直到至少 500 ms 没有网络活动”;solve_cloudflare 表示“在返回响应前解决所有类型的 Cloudflare Turnstile/Interstitial 质询”;google_search 默认启用,会设置 Google 来源 Referer;
  • 会话管理FetcherSessionStealthySessionDynamicSession 三类持久会话类,用于跨请求维持 Cookie 与状态;
  • Proxy 轮换:内置 ProxyRotator,支持顺序(cyclic)或自定义轮换策略,可用于所有会话类型,并支持按请求覆盖 Proxy(实现见 scrapling/engines/toolbelt/proxy_rotation.py);
  • 域名/广告拦截:可拦截特定域名(含子域)的请求,或启用内置广告拦截(约 3500 个已知广告/追踪域名,见 scrapling/engines/toolbelt/ad_domains.py);
  • DNS 泄漏防护:可选 DNS-over-HTTPS,将 DNS 查询经 Cloudflare DoH 路由,避免使用代理时发生 DNS 泄漏;
  • 远程浏览器:通过 cdp_url 用 CDP 连接已在运行的浏览器(本机、远程主机或托管浏览器服务);也可用 executable_path 让任意浏览器 Fetcher 指向你自己的 Chromium 构建;
  • 后台 API 捕获:给 capture_xhr 传入 URL 模式,页面加载期间所有匹配的 XHR/fetch 响应会被收集为 Response 对象存入 response.captured_xhr——无需逆向工程即可拿到站点 API 数据;
  • 完整 Async 支持:所有 fetcher 均有对应的 async 类与会话类。

从源码结构看,scrapling/fetchers/init.py 采用了惰性导入(_LAZY_IMPORTS 映射 + 模块级 __getattr__):Fetcher/AsyncFetcher/FetcherSession 来自 scrapling.fetchers.requestsDynamicFetcher/DynamicSession/AsyncDynamicSession 来自 scrapling.fetchers.chromeStealthyFetcher/StealthySession/AsyncStealthySession 来自 scrapling.fetchers.stealth_chrome。这也解释了为什么只装基础包时导入 scrapling.fetchers 里的任何类会抛出 ModuleNotFoundError——底层依赖(如 curl_cffi、Playwright)属于可选依赖组。

自适应抓取与 AI 集成

  • 智能元素追踪:基于相似度算法在网站改版后重新定位元素。解析器入口 scrapling/parser.pySelector 的构造参数包含 adaptive: Optional[bool] = False,文档注释说明该参数是“全局关闭自适应功能”的总开关,且优先级高于所有 adaptive 相关方法/参数——即 adaptive 能力默认关闭,需要显式开启
  • 灵活的选择方式:CSS 选择器、XPath、基于过滤器的查找、文本查找、正则查找等(详见 docs/parsing/selection.md);
  • 相似元素查找:自动定位与已找到元素相似的其他元素(find_similar());
  • MCP 服务器:内置 Model Context Protocol 服务器,用于 AI 辅助的 Web 抓取与数据提取;它先利用 Scrapling 提取目标内容再交给 AI(Claude/Cursor 等),以减少 token 消耗,还支持跨调用保持浏览器会话、页面截图与 CDP 远程浏览器控制(说明文档见 docs/ai/mcp-server.md);
  • Agent Skill:仓库内提供开箱即用的 agent-skill 目录(含 SKILL.md 与完整的参考文档),教编程 Agent 使用与当前 API 一致的 Scrapling 写法,避免“靠猜”生成代码。

高性能架构与开发体验

README 的性能主张(均以仓库官方表述为准):解析速度超过大多数 Python Web 抓取库、内存占用优化(惰性加载)、JSON 序列化比标准库快约 10 倍、测试覆盖率 92% 且具备完整类型提示(每次变更用 PyRight 与 MyPy 扫描全量源码)。

开发者体验方面的特性包括:可选的 IPython 交互 Shell(含 curl 转 Scrapling 请求、在浏览器中查看请求结果等快捷工具)、直接通过终端命令抓取 URL 而无需写代码、丰富的 DOM 导航 API(父/兄弟/子元素)、内置 regex 与字符串清洗方法、CSS/XPath 选择器自动生成、与 Scrapy/BeautifulSoup 相似且兼容 Scrapy/Parsel 伪元素(::text::attr() 等)的 API,以及与 Scrapy 的直接集成——用 scrapling_response 装饰器即可把 Scrapy 回调里已有的响应交给 Scrapling 解析器(集成代码见 scrapling/integrations/scrapy.py)。

快速上手

基础用法:三种 Fetcher + 对应会话

以下示例完整继承自 README(docs/README_ES.md 的“Primeros Pasos”一节)。

HTTP 请求(带会话支持)——Fetcher 可模仿 Chrome 最新 TLS 指纹:

from scrapling.fetchers import Fetcher, FetcherSession

with FetcherSession(impersonate='chrome') as session:  # 使用最新版 Chrome TLS 指纹
    page = session.get('https://quotes.toscrape.com/', stealthy_headers=True)
    quotes = page.css('.quote .text::text').getall()

# 或者使用一次性请求
page = Fetcher.get('https://quotes.toscrape.com/')
quotes = page.css('.quote .text::text').getall()

高级隐身模式——solve_cloudflare=True 会在返回前自动通过 Cloudflare 质询;StealthySession 会保持浏览器打开直到你结束所有请求:

from scrapling.fetchers import StealthyFetcher, StealthySession

with StealthySession(headless=True, solve_cloudflare=True) as session:
    page = session.fetch('https://nopecha.com/demo/cloudflare', google_search=False)
    data = page.css('#padded_content a').getall()

# 或者用一次性请求风格:为此请求打开浏览器,完成后自动关闭
page = StealthyFetcher.fetch('https://nopecha.com/demo/cloudflare')
data = page.css('#padded_content a').getall()

完整浏览器自动化——DynamicFetcher 走标准 Playwright 路线,也支持 XPath:

from scrapling.fetchers import DynamicFetcher, DynamicSession

with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session:
    page = session.fetch('https://quotes.toscrape.com/', load_dom=False)
    data = page.xpath('//span[@class="text"]/text()').getall()  # 如果你喜欢 XPath

# 或者一次性请求风格
page = DynamicFetcher.fetch('https://quotes.toscrape.com/')
data = page.css('.quote .text::text').getall()

三者如何取舍,仓库有专门文档给出速度、隐身性、反爬选项、JS 加载能力、内存占用等维度的对比表,见 docs/fetching/choosing.md。简言之:纯 HTTP 就能搞定的场景用 Fetcher;动态加载、小自动化与中小防护用 DynamicFetcher;更复杂的防护与 Cloudflare 质询用 StealthyFetcher

按请求或全局配置解析器

所有 Fetcher 共享同一套解析器配置接口(来自 docs/fetching/choosing.md)。先于请求调用 configure,或直接设置类属性:

from scrapling.fetchers import Fetcher
Fetcher.configure(adaptive=True, keep_comments=False, keep_cdata=False)  # 其余参数同

# 或者
Fetcher.adaptive = True
Fetcher.keep_comments = False
Fetcher.keep_cdata = False

可用配置参数为:adaptiveadaptive_domainhuge_treekeep_commentskeep_cdatastoragestorage_args——与 Selector 类 的构造参数一致。任意时刻可用 <fetcher_class>.display_config() 打印当前配置。如前所述,adaptive 参数在 scrapling/parser.py#L89 中默认为 False,必须显式开启。

Spiders:并发爬取、多会话与断点续爬

基础并发爬虫(完整继承自 README):

from scrapling.spiders import Spider, Request, Response

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

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

        next_page = response.css('.next a')
        if next_page:
            yield response.follow(next_page[0].attrib['href'])

result = QuotesSpider().start()
print(f"Se extrajeron {len(result.items)} citas")  # 打印提取条数
result.items.to_json("quotes.json")

单个 Spider 内混用多种会话类型——受保护页面走隐身会话,其余走快速 HTTP 会话,sid 即会话路由 ID:

from scrapling.spiders import Spider, Request, Response
from scrapling.fetchers import FetcherSession, AsyncStealthySession

class MultiSessionSpider(Spider):
    name = "multi"
    start_urls = ["https://example.com/"]

    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", callback=self.parse)  # 显式 callback

Pause & Resume:给 Spider 传入 crawldir 即启用 Checkpoint 持久化:

QuotesSpider(crawldir="./crawl_data").start()

Ctrl+C 会优雅暂停并自动保存进度;再次启动同一 crawldir 时从断点继续。这与源码中 crawldir “If provided, enables pause/resume” 的注释(scrapling/spiders/spider.py#L106)一致。

直接用模板——例如抓取任意 Shopify 商店全部商品(每变体一条):

from scrapling.spiders import ShopifySpider

class MyStore(ShopifySpider):
    target_website = "example.com"

result = MyStore().start()  # 商店全部商品,一个变体一个条目

高级解析与 DOM 导航

不抓取网页时也可直接使用解析器:from scrapling.parser import Selector; page = Selector("<html>...</html>"),用法与 Fetcher 返回的页面完全一致。README 给出的完整解析示例:

from scrapling.fetchers import Fetcher

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

# 多种选择方式
quotes = page.css('.quote')                       # CSS 选择器
quotes = page.xpath('//div[@class="quote"]')      # XPath
quotes = page.find_all('div', {'class': 'quote'}) # BeautifulSoup 风格
# 等价写法
quotes = page.find_all('div', class_='quote')
quotes = page.find_all(['div'], class_='quote')
quotes = page.find_all(class_='quote')           # 以此类推...
# 按文本内容查找
quotes = page.find_by_text('quote', tag='div')

# 高级导航
quote_text = page.css('.quote')[0].css('.text::text').get()
quote_text = page.css('.quote').css('.text::text').getall()  # 链式选择器
first_quote = page.css('.quote')[0]
author = first_quote.next_sibling.css('.author::text')
parent_container = first_quote.parent

# 元素关系与相似度
similar_elements = first_quote.find_similar()
below_elements = first_quote.below_elements()

Async 会话管理示例

FetcherSession 同时兼容 sync/async 上下文;AsyncStealthySession 支持多标签页池并发,可用 get_pool_stats() 查看标签页池状态(占用/空闲/错误):

import asyncio
from scrapling.fetchers import FetcherSession, AsyncStealthySession, AsyncDynamicSession

async with FetcherSession(http3=True) as session:  # 上下文感知,sync/async 模式均可用
    page1 = session.get('https://quotes.toscrape.com/')
    page2 = session.get('https://quotes.toscrape.com/', impersonate='firefox135')

# 使用 async 会话
async with AsyncStealthySession(max_pages=2) as session:
    tasks = []
    urls = ['https://example.com/page1', 'https://example.com/page2']

    for url in urls:
        task = session.fetch(url)
        tasks.append(task)

    print(session.get_pool_stats())  # 可选 - 浏览器标签页池状态(占用/空闲/错误)
    results = await asyncio.gather(*tasks)
    print(session.get_pool_stats())

CLI 与交互式 Shell

Scrapling 自带命令行界面(命令注册见 scrapling/cli.pyinstallshellextractmcp 四个子命令),文档见 docs/cli/overview.md

启动 Web 抓取交互式 Shell

scrapling shell

不写任何代码直接提取页面到文件:默认提取 <body> 内容,输出格式由扩展名决定——.txt 输出纯文本,.md 输出 Markdown 表示,.html 输出 HTML 本体:

scrapling extract get 'https://example.com' content.md
scrapling extract get 'https://example.com' content.txt --css-selector '#fromSkipToProducts' --impersonate 'chrome'
scrapling extract fetch 'https://example.com' content.md --css-selector '#fromSkipToProducts' --no-headless
scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' captchas.html --css-selector '#padded_content a' --solve-cloudflare

性能基准

README 引用了仓库官方基准(数据见 docs/benchmarks.md,方法学脚本为 benchmarks.py,均为 100 次以上运行的平均值)。

文本提取速度(5000 个嵌套元素)

# 耗时 (ms) 相对 Scrapling
1 Scrapling 1.99 1.0x
2 Parsel/Scrapy 2.06 1.035
3 Raw Lxml 2.56 1.286
4 PyQuery 23.98 ~12x
5 Selectolax 197.02 ~99x
6 MechanicalSoup 1545.15 ~776.5x
7 BS4 + Lxml 1562.1 ~785.0x
8 BS4 + html5lib 3412.73 ~1714.9x

自适应元素查找 / 文本搜索

耗时 (ms) 相对 Scrapling
Scrapling 2.3 1.0x
AutoScraper 12.58 5.47x

注意:以上为仓库官方文档公布的对比数据,复现时以 benchmarks.py 中的方法学为准;实际表现会随运行环境、库版本变化。

安装与部署

Scrapling 要求 Python 3.10 或更高版本pyproject.tomlrequires-python = ">=3.10")。

1. 基础安装(仅解析引擎)

pip install scrapling

重要:基础安装只包含解析引擎及其依赖,不含任何 Fetcher 与命令行依赖。此时从 scrapling.fetchersscrapling.spiders 导入任何内容都会抛出 ModuleNotFoundError。如需使用 Fetcher 或 Spider,必须先安装 fetchers 依赖组。

2. 安装 Fetchers 与浏览器依赖

pip install "scrapling[fetchers]"

scrapling install           # 常规安装
scrapling install --force   # 强制重装

这会在本地下载所有浏览器及其系统依赖与指纹处理依赖。也可以从代码中安装:

from scrapling.cli import install

install([], standalone_mode=False)           # 常规安装
install(["--force"], standalone_mode=False)  # 强制重装

scrapling/cli.py#L120-L142install 实现可以看到,它实际执行了三件事:python -m playwright install chromiumpython -m playwright install-deps chromium,以及更新 tld 域名数据,完成后写入 .scrapling_dependencies_installed 标记文件——标记已存在且未加 --force 时直接提示 “The dependencies are already installed”。

3. 可选依赖组(对应 pyproject.toml#L72-L96 中的 optional-dependencies 定义):

pip install "scrapling[ai]"      # MCP 服务器功能
pip install "scrapling[shell]"   # Web 抓取 Shell 与 extract 命令
pip install "scrapling[all]"     # 全部功能

其中 [fetchers] 依赖组包含 clickcurl_cffiplaywrightpatchrightbrowserforgeapify-fingerprint-datapointsmsgspecanyioprotego[ai] 额外需要 mcpmarkdownify 并自动带入 [fetchers][shell] 依赖 IPython>=8.37(最后一个支持 Python 3.10 的版本线)、markdownify[fetchers]。无论装哪个 extra,只要用到浏览器 Fetcher,都别忘了再执行一次 scrapling install

4. Docker 方式(每个 release 会自动构建并推送包含全部 extras 与浏览器的镜像):

docker pull pyd4vinci/scrapling
# 或从 GitHub 容器注册表:
docker pull ghcr.io/d4vinci/scrapling:latest

使用须知与延伸阅读

总结来说,Scrapling 的架构思路是“一个库、三种抽象”:Selector 负责会“自愈”的解析,Fetcher/DynamicFetcher/StealthyFetcher(及其 Session 变体)负责从纯 HTTP 到反爬规避的抓取,Spider 框架负责把前两者放大为可断点续爬、可流式消费、可多会话路由的并发爬取任务。理解这三层及它们之间 Response 对象的衔接,就掌握了使用整套框架的关键。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
981
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384