首页
/ Scrapling 完全指南:自适应 Web Scraping 框架的 Fetcher、Spider 与 CLI 全解析

Scrapling 完全指南:自适应 Web Scraping 框架的 Fetcher、Spider 与 CLI 全解析

2026-09-04 11:28:17作者:董宙帆

Scrapling 是一个从单次请求到全规模爬取都能覆盖的自适应 Web Scraping 框架:其解析器会从网站变更中“学习”并自动重新定位元素,Fetcher 可绕过 Cloudflare Turnstile 等反爬机制,Spider 框架则提供暂停恢复(Pause & Resume)、自动代理轮换与并发多 Session 爬取能力。本文基于仓库官方文档与源码,完整梳理 Scrapling 的核心特性、四类 Fetcher/Session 的实战用法、Spider 爬取框架、CLI 与交互式 Shell,以及安装体系与性能基准,读完即可在 Python 3.10+ 环境下独立搭建一个从“抓一页”到“爬全站”的完整抓取系统。

Scrapling Spider 爬取引擎架构示意图,展示 Spider、Engine、Session 与 Checkpoint 各组件关系

框架定位与核心特性

Scrapling 的定位可以概括为一句话:“一个库,无需妥协”。官方文档给出的最小示例直观展示了它的两大招牌能力——隐身获取 + 自适应解析:

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 重新找到它!

或直接升级为正式爬取:

from scrapling.spiders import Spider, Response

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

  async def parse(self, response: Response):
      for item in response.css('.product'):
          yield {"title": item.css('h2::text').get()}

MySpider().start()

Spider:正式级爬取框架

Spider 子系统是 Scrapling 区别于“单页抓取库”的关键,特性列表如下:

  • Scrapy 风格 Spider API:通过 start_urls、异步 parse 回调、Request/Response 对象定义 Spider;
  • 并发爬取:可配置的并发数上限、按域名限流(throttling)、下载延迟;
  • 多 Session 支持:HTTP 请求与隐身无头浏览器共享统一接口,可按 ID 把请求路由到不同 Session;
  • Pause & Resume:基于 Checkpoint 的爬取持久化,Ctrl+C 优雅停机,重启后从断点继续;
  • Streaming 模式async for item in spider.stream() 带实时统计地流式接收结果,适合 UI、管道与长时任务;
  • 被阻塞请求检测:可自定义逻辑自动检测被拦截的请求并重试;
  • AutoThrottle:Spider 根据站点响应速度自动调整每域名等待时间,被限流时等待时间翻倍(或按 Retry-After 等待),恢复后再加速;
  • robots.txt 遵从:可选 robots_txt_obey 标志,配合每域名缓存遵守 DisallowCrawl-delayRequest-rate 指令;
  • 开发模式:首次运行时将响应缓存到磁盘,后续运行回放缓存,无需反复请求目标服务器即可迭代 parse() 逻辑;
  • 即用型 Spider 模板CrawlSpider(规则式链接跟随)、SitemapSpider(从 sitemap/robots.txt 起步)、XMLFeedSpider/CSVFeedSpider(XML/RSS/CSV 源)、ShopifySpider(通过 JSON API 获取任意 Shopify 商店全部商品,每个变体一条记录);
  • 链接抽取:独立 LinkExtractor,支持 allow/deny 模式、域名过滤、CSS/XPath 作用域、扩展名过滤与 URL 规范化;
  • 内建导出result.items.to_json()to_jsonl()to_csv()to_xml(),无需自建管道。

从源码结构看,这些能力落在 scrapling/spiders/ 目录中:spider.py 定义 concurrent_requests 等默认值(全局并发默认 4,spider.py),engine.pyCrawlerEngineCapacityLimiter 分别实现全局与每域名并发上限(engine.py);传入 crawldir 即启用 CheckpointManager 做断点持久化(checkpoint.py)。

带 Session 的高级网站获取

四类 Fetcher/Session 覆盖从纯 HTTP 到完全浏览器自动化的需求:

  • HTTP 请求Fetcher 类,快速且隐身的 HTTP 请求,模仿真实浏览器 TLS 指纹与请求头,支持 HTTP/3;
  • 动态加载DynamicFetcher,基于 Playwright 的 Chromium 与 Google Chrome 的完整浏览器自动化;
  • 反反爬StealthyFetcher 配合指纹伪装的高级隐身能力,可绕过 Cloudflare Turnstile/Interstitial 各类场景;
  • Session 管理FetcherSessionStealthySessionDynamicSession 提供跨请求的 Cookie 与状态持久化;
  • 代理轮换:内置 ProxyRotator,支持轮询(round-robin)或自定义策略,覆盖全部 Session 类型,且可逐请求覆盖代理;
  • 域名与广告拦截:浏览器类 Fetcher 可拦截指定域名(含子域名),或启用内建广告拦截(覆盖约 3,500 个已知广告/追踪域名,见 engines/toolbelt/ad_domains.py);
  • DNS 泄漏防护:可选的 DNS-over-HTTPS,通过 Cloudflare DoH 路由 DNS 查询,防止使用代理时泄漏本地 DNS;
  • 远程浏览器:通过 cdp_url 连接已运行的浏览器(本机、异机或托管浏览器服务均可);executable_path 可把任意浏览器 Fetcher 指向自编译的 Chromium;
  • 后台 API 捕获:给 capture_xhr 传 URL 模式,页面加载期间命中的 XHR/fetch 响应会全部作为 Response 对象收集到 response.captured_xhr,无需逆向接口即可拿到站点 API 数据;
  • async 支持:所有 Fetcher 与专用异步 Session 类均提供完整 async 实现。

从源码结构看,scrapling/fetchers/init.py 采用惰性导入(_LAZY_IMPORTS 映射 + 模块级 __getattr__):只有真正访问 StealthyFetcher 等属性时才加载对应引擎模块,这也是“只装解析器就能导入包”而不拖入重型依赖的原因之一。

自适应抓取与 AI 集成

  • 智能元素追踪:使用智能相似度算法在网站变更后重新定位元素;
  • 智能灵活选择:CSS 选择器、XPath、过滤式检索、文本检索、正则检索等;
  • 相似元素检测:自动找出与目标元素相似的元素(find_similar());
  • MCP 服务器:内建 MCP(Model Context Protocol)服务器,让 AI 助手在把网页内容交给模型前先经 Scrapling 抽取,减少 token 消耗;支持跨多次调用维持浏览器会话、截图、通过 CDP 操作远程浏览器(见 scrapling/core/ai.py);
  • Agent Skill:安装即用的 Agent 技能包,把整套库的当前 API 教给编码代理,避免生成“凭想象”的代码(见 agent-skill/)。

自适应能力在解析器源码中有明确约束:Selector 实例需以 adaptive=True 初始化才会启用该体系,若未启用,css() 中传入的 auto_save=True 会被忽略并给出提示(parser.py);选择方法本身支持 adaptiveauto_saveidentifierpercentage 参数,percentage 是自适应匹配可接受的最低相似度阈值(parser.py)。

高性能实战验证的架构

  • 极速:官方基准下性能超过大多数 Python 爬虫库;
  • 内存效率:优化数据结构与惰性加载,追求最小内存占用;
  • 快速 JSON 序列化:基于 orjson,官方称较标准库快约 10 倍(pyproject.tomlorjson>=3.11.8 为核心依赖);
  • 实战验证:官方称具备 92% 测试覆盖率与完整类型提示覆盖,整个代码库在每次变更时经 PyRight 与 MyPy 自动扫描。

开发者友好体验

  • 交互式 Web 抓取 Shell:可选的内建 IPython Shell,内置 Scrapling 集成、快捷键、把 curl 请求转成 Scrapling 请求、在浏览器中查看结果等工具;
  • 命令行直接抓取:不写一行代码即可用 CLI 抓取 URL;
  • 丰富的导航 API:父/兄弟/子节点导航方法实现高级 DOM 遍历;
  • 增强文本处理:内建正则、清洗方法、优化字符串操作;
  • 自动选择器生成:为任意元素生成稳健的 CSS/XPath 选择器;
  • 熟悉度高的 API:与 Scrapy/BeautifulSoup 设计相近,使用 Scrapy/Parsel 同款伪元素;
  • Scrapy 无缝集成:用 scrapling_response 装饰任意回调,即可把 Scrapy 已获取的响应交给 Scrapling 解析器(见 scrapling/integrations/scrapy.pydocs/integrations/scrapy.md);
  • 完整类型覆盖:全库类型提示,IDE 补全友好;
  • Docker 镜像:每个 release 自动构建并推送包含全部浏览器的镜像。

快速上手

基本用法

带 Session 的 HTTP 请求

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()

高级隐身模式

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()

solve_cloudflare=True 对应 CLI 侧的 --solve-cloudflare 选项(cli.py),启用后会在无头浏览器中等待 Cloudflare 质询通过。

完整浏览器自动化

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()

Spider 实战

构建带并发、多 Session 类型与 Pause & Resume 的正式爬虫:

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"已抓取 {len(result.items)} 条名言")
result.items.to_json("quotes.json")

start() 返回 CrawlResult,其统计字段包含 concurrent_requestsconcurrent_requests_per_domain 等(result.py);start(use_uvloop=False, **backend_options) 还支持事件循环后端调优(spider.py)。

单个 Spider 中混合多 Session 类型

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():
            # 受保护页面走隐身 Session
            if "protected" in link:
                yield Request(link, sid="stealth")
            else:
                yield Request(link, sid="fast", callback=self.parse)  # 显式 callback

configure_sessions 由 Spider 基类在初始化时调用,若未添加任何 Session 会抛出 SessionConfigurationErrorspider.py),lazy=True 让浏览器 Session 按需启动。

用 Checkpoint 实现长时间爬取的 Pause & Resume

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

Ctrl+C 会优雅暂停并自动保存进度;再次以相同 crawldir 启动时从断点恢复。crawldir 传入 CrawlerEngine 后由 CheckpointManagercrawldir 下创建 checkpoint 文件,默认保存间隔 300 秒(checkpoint.pyspider.py)。

用现成模板跳过爬虫逻辑——例如整站抓取 Shopify 商店目录:

from scrapling.spiders import ShopifySpider

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

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

ShopifySpidertarget_website(或 start_urls/allowed_domains)解析出商店域名,随后通过其 JSON API 的 collections/products 端点翻页抓取(templates/shopify.py)。更多模板(CrawlSpiderSitemapSpider、Feed 系列)见 docs/spiders/generic-templates.mddocs/spiders/platform-templates.md

高级解析与导航

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()

这些方法(css/xpath/find_all/find_by_text/find_similar)均定义在 scrapling/parser.py 中。不获取网站也能直接使用解析器:

from scrapling.parser import Selector

page = Selector("<html>...</html>")

用法完全一致。

异步 Session 管理示例

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

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

# 使用异步 Session
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())

get_pool_stats() 在浏览器引擎层实现,返回标签池的 busy/free/error 计数(engines/_browsers/_base.pyL313)。

CLI 与交互式 Shell

scrapling 命令行与交互式 Shell 运行截图,展示 curl 命令转换为 Scrapling 请求与页面查看效果

Scrapling 附带功能强大的命令行界面,安装后即获得 scraplingscrapling-mcp 两个控制台入口(pyproject.toml)。

启动交互式 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'  # 所有匹配该 CSS 选择器的元素
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

从源码看,extract 子命令组在 cli.py 中注册 --css-selector--headless/--no-headless 等选项,另有 --solve-cloudflare 选项透传给隐身引擎(cli.py)。更多命令细节见 docs/cli/overview.mddocs/cli/extract-commands.mddocs/cli/interactive-shell.md;MCP 服务器配置见 docs/ai/mcp-server.md

性能基准

官方基准将 Scrapling 解析器与主流库的最新版本对比,结果如下(数据来自官方文档,方法学见 benchmarks.py)。

文本抽取速度测试(5000 个嵌套元素)

# 耗时 (ms) 相对 Scrapling
1 Scrapling 1.99 1.0x
2 Parsel/Scrapy 2.06 1.035x
3 Raw Lxml 2.56 1.286x
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

从源码看,基准脚本用 5000 个 <div class="item"> 拼接的大页面构造测试数据,先做预热,再用 timeit.repeattime.process_time 计时)重复 100 次取平均(benchmarks.py),Scrapling 一侧刻意关闭自适应(adaptive=False)以保证公平对比。复现方式:

pip install -r tests/requirements.txt  # 或手动安装基准依赖
python benchmarks.py

安装

Scrapling 需要 Python 3.10+(pyproject.toml 声明 requires-python = ">=3.10",官方镜像测试覆盖 3.10–3.13;当前仓库版本为 0.4.13)。

pip install scrapling

重要:基础安装只包含解析器引擎及其依赖(lxmlcssselectorjsontldw3libtyping_extensions)。此时从 scrapling.fetchersscrapling.spiders 导入会触发 ModuleNotFoundError。需要使用 Fetcher 或 Spider 时,先安装 Fetcher 依赖:

可选依赖

  1. Fetcher + 浏览器依赖
pip install "scrapling[fetchers]"

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

这会下载全部浏览器及其系统依赖与指纹操作依赖。fetchers 扩展的实际依赖包括 curl_cffi(TLS 指纹伪装)、playwrightpatchright(浏览器自动化)、browserforgeapify-fingerprint-datapoints(指纹数据)、protego(robots.txt 解析)等(pyproject.toml)。也可以在代码中执行安装:

from scrapling.cli import install

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

对应实现位于 cli.py

  1. 其他扩展
    • MCP 服务器功能:pip install "scrapling[ai]"
    • Shell 功能(Web 抓取 Shell 与 extract 命令):pip install "scrapling[shell]"
    • 全部功能:pip install "scrapling[all]"
    • 安装以上任一扩展后,若浏览器依赖尚未安装,仍需执行 scrapling install

Docker

从 DockerHub 拉取包含全部扩展与浏览器的镜像:

docker pull pyd4vinci/scrapling

或从容器注册表拉取:

docker pull ghcr.io/d4vinci/scrapling:latest

该镜像随 GitHub Actions 与主分支自动构建推送(构建定义见 Dockerfile)。

贡献、引用与法律说明

  • 贡献:欢迎贡献,开始前请阅读 CONTRIBUTING.md
  • 免责声明:本库仅用于教育与研究目的。使用本库即表示你同意遵守当地及国际数据抓取与隐私法规;作者与贡献者不对软件误用负责。请始终尊重网站服务条款与 robots.txt;
  • 学术引用
@misc{scrapling,
  author = {Karim Shoair},
  title = {Scrapling},
  year = {2024},
  note = {An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!}
}
  • 许可:本作品采用 BSD-3-Clause 许可(见 LICENSE);
  • 致谢:项目包含自 Parsel(BSD 许可)适配而来的代码,用于 scrapling/core/translator.py 子模块(XPath 到 CSS 的转换)。

小结

Scrapling 把“单页抓取”与“全站爬取”统一在一个库中:Fetcher/DynamicFetcher/StealthyFetcher 三层获取能力覆盖 HTTP 指纹伪装到无头浏览器反反爬,Selectoradaptive/auto_save 机制让选择器能跨越网站改版存活,Spider 框架则提供并发、多 Session、AutoThrottle、Checkpoint 断点续爬与 Streaming 等生产级特性,再辅以 CLI、交互式 Shell、MCP 服务器与 Docker 镜像构成完整工具链。按本文的“基础安装 → scrapling[fetchers] + scrapling install → 选择 Fetcher/Spider 模式”的路径落地,即可在现有项目中快速集成。

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

项目优选

收起
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
982
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384