首页
/ Scrapling 实战指南:从单条请求到全量爬取的自适应 Web Scraping 框架

Scrapling 实战指南:从单条请求到全量爬取的自适应 Web Scraping 框架

2026-09-04 15:37:32作者:咎岭娴Homer

本文基于 Scrapling 仓库的官方项目说明文档 README_PT_BR.md(葡语版 README,内容与英文主 README 保持同步)整理而成,覆盖其三大核心能力——自适应解析器、多类型 Fetcher 与会话管理、Scrapy 风格的 Spider 框架——并结合同仓库源码逐条印证关键特性的实现位置。读完后你将能够独立完成:带 TLS 指纹仿冒的 HTTP 请求、可绕过 Cloudflare Turnstile 的隐身浏览器抓取、并发爬取与断点续传,以及不写代码的命令行快速提取。

Scrapling Spider 爬取引擎架构

框架定位与整体能力

Scrapling 是一个自适应的 Web Scraping 框架,官方定位是“从单条请求到大规模爬取全部搞定”(An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl)。其三大支柱在文档中表述非常明确:

  • 自适应解析器:从源码结构看,解析器在首次提取时会记录元素特征并持久化(见 parser.pyadaptive/auto_save 参数逻辑),当目标页面改版导致 CSS 选择器失效时,通过相似度算法重新定位元素,而无需重写选择器;
  • 隐身 Fetchers:内置 StealthyFetcher 等浏览器自动化引擎,可原生绕过 Cloudflare Turnstile/Interstitial 等反爬机制;
  • Spider 框架:支持并发爬取、多会话路由、checkpoint 断点续传与自动代理轮换。

文档开头给出的最小示例展示了“一条请求 + 自适应提取”的完整闭环:

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 重新定位

核心特性解析

Spiders:完整的爬虫框架

文档将 Spider 子系统列为第一大特性板块,其能力点可归纳为以下八项,且均能在仓库源码中找到对应实现:

特性 说明 源码佐证
Scrapy 风格 API start_urls、异步 parse 回调、Request/Response 对象 spider.pyrequest.py
并发控制 全局与按域名的并发上限、下载延迟 concurrent_requestsconcurrent_requests_per_domaindownload_delay 类属性
多会话路由 单只 Spider 内混用 HTTP 与隐身浏览器会话,按 ID 分流请求 session.py 中的 SessionManager
暂停/续爬 基于 checkpoint 的持久化,Ctrl+C 优雅退出后从断点恢复 checkpoint.py,构造参数 crawldir
流式模式 async for item in spider.stream() 实时消费提取项与统计 result.pyCrawlResult
阻塞检测 自动识别被拦截请求并重试,策略可自定义 spider.pyBLOCKED_CODES = {401, 403, 407, 429, 444, 500, 502, 503, 504}
AutoThrottle 根据目标响应速度自动调节每域延迟;遇限流/封锁时加倍延迟或遵循 Retry-After,恢复后自动提速 autothrottle_* 系列类属性(见 spider.py
robots.txt 合规 可选 robots_txt_obey 开关,尊重 DisallowCrawl-delayRequest-rate,按域缓存 robotstxt.py

spider.py 的类属性定义可以进一步确认若干文档未逐一列出的默认值:concurrent_requests = 4(默认并发 4)、max_blocked_retries = 3(被拦截请求最多重试 3 次)、autothrottle_start_delay = 5.0 秒、autothrottle_max_delay = 60.0 秒;Spider.__init__ 接受 crawldir(启用 checkpoint 持久化的目录)与 interval(周期性 checkpoint 保存间隔,默认 300 秒)。此外还有“开发模式”:development_mode 开启后首次运行的响应会被落盘缓存,后续迭代 parse() 逻辑时直接回放缓存,不再向目标服务器发请求。

Spider 模板库位于 templates/init.py,从源码确认了文档列出的四类模板全部可用:

  • CrawlSpider:按规则跟随链接;
  • SitemapSpider:以 sitemap/robots.txt 驱动的爬取;
  • XMLFeedSpider / CSVFeedSpider:迭代 XML/RSS/CSV 数据源;
  • ShopifySpider:通过 Shopify 的 JSON API 抓取任意店铺的全部商品,一个 SKU 变体一个数据项。

配套还有独立原语 LinkExtractorlinks.py),支持 allow/deny 正则、域名过滤、CSS/XPath 限定范围、扩展名过滤与 canonical 化,既可配合模板使用,也可单独使用。提取结果可通过钩子、自定义 pipeline 或原生导出器落盘:result.items.to_json()to_jsonl()to_csv()to_xml()

带会话的站点抓取:三类 Fetcher + 代理轮换

抓取层的类导出关系在 fetchers/init.py 中通过惰性导入映射定义,共三类引擎、每类都有同步/异步与一次性/会话两种形态:

  • Fetcher / AsyncFetcher / FetcherSession:基于 curl_cffi 的快速 HTTP 请求(见 pyproject.tomlfetchers 依赖),可仿冒浏览器 TLS 指纹、自定义请求头、启用 HTTP/3;
  • DynamicFetcher / DynamicSession / AsyncDynamicSession:完整的 Playwright 浏览器自动化,兼容 Chromium 与 Google Chrome;
  • StealthyFetcher / StealthySession / AsyncStealthySession:基于 Patchright 的隐身自动化,具备指纹伪装能力,可处理各类 Cloudflare Turnstile/Interstitial 拦截。

除三类引擎外,文档列出的会话级能力还包括:ProxyRotator 原生代理轮换(支持轮换策略或自定义策略,且支持单请求级 proxy 覆盖,实现位于 proxy_rotation.py);基于域名及其子域的请求拦截,以及内置约 3500 个广告/追踪域名的原生广告拦截(域表见 ad_domains.py);可选 DNS-over-HTTPS(走 Cloudflare DoH),在使用代理时避免 DNS 泄漏;通过 cdp_url 连接远端已运行浏览器(本地、异地或托管浏览器服务),或通过 executable_path 指向自定义 Chromium 构建;capture_xhr 参数传入 URL 模式后,页面加载期间所有匹配的 XHR/fetch 响应会被收集到 response.captured_xhr,等于免逆向直接拿到目标 API 数据;全部 Fetcher 均提供完整的 async 版本。

自适应解析与 AI 集成

解析层是 Scrapling 的核心差异化能力:

  • 元素智能追踪:页面改版后依据相似度算法重新定位元素。从 parser.py 的源码看,Selector 构造时可用 adaptive 参数全局开启自适应,css()/xpath() 等提取方法再分别接受 adaptive=True(对已保存元素执行重定位)与 auto_save=True(首次提取时保存元素特征)两个参数,且存在优先级约束:若实例未启用自适应,auto_save 会被忽略并给出提示;
  • 多元选择方式:CSS 选择器、XPath、基于过滤器的查找、按文本查找、正则查找,以及 find_similar() 自动发现相似元素、below_elements() 等结构关系方法;
  • MCP 服务器:原生 MCP Server 面向 AI 辅助抓取场景(文档与 docs/ai/mcp-server.md 对应),支持在把内容交给 Claude/Cursor 等模型之前做定向提取以降低 token 消耗,还能在多次调用间保持浏览器会话、截图页面、经 CDP 控制远程浏览器;仓库同时提供了可直接安装的 Agent Skill(agent-skill/Scrapling-Skill/SKILL.md),让编码 Agent 按当前 API 而非猜测来生成 Scrapling 代码;
  • 性能与质量:文档声明 JSON 序列化比标准库快 10 倍(底层使用 orjson,见 pyproject.toml 的依赖列表)、测试覆盖率 92% 且全量 type hints,整个 codebase 每次变更都会被 PyRight 与 MyPy 扫描(pyproject.toml 中可见两项静态检查配置)。

开发者体验

文档还列出了一组工程侧特性:基于 IPython 的交互式抓取 Shell(scrapling shell,内置 curl 转 Scrapling 请求、浏览器预览结果等工具);纯命令行不写代码直接提取 URL;丰富的 DOM 导航 API(父节点、兄弟节点、子节点遍历);原生正则/文本清洗方法;为任意元素自动生成稳健的 CSS/XPath 选择器;与 Scrapy/BeautifulSoup 风格一致的 API 和 Scrapy/Parsel 同款伪元素;通过 scrapling_response 装饰器把 Scrapy 回调的响应无缝切换为 Scrapling 解析(实现见 integrations/scrapy.py),以及每次 release 自动构建并发布带全部浏览器的 Docker 镜像(构建定义见 Dockerfile)。

快速上手

基础用法:三种抓取形态

带会话的 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()

隐身模式(Cloudflare 绕过)

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

完整浏览器自动化

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

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

构建一个带分页跟随的并发爬虫:

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"Extraídas {len(result.items)} citações")
result.items.to_json("quotes.json")

在单只 Spider 中混合使用多种会话,通过 sid 把不同链接路由到不同抓取引擎:

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)  # 显式回调

暂停/续爬只需把 checkpoint 目录传给 start() 的构造参数:

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

按 Ctrl+C 优雅暂停,进度自动保存;再次启动时传入相同 crawldir 即从断点继续。结合上文源码分析,checkpoint 默认每 300 秒自动落盘一次,退出时再保存一次。

用模板跳过爬虫样板代码,例如直接抓取整站 Shopify 商品:

from scrapling.spiders import ShopifySpider

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

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

高级解析与导航

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

不抓取网站时也可直接使用解析器,行为与抓取结果完全一致:

from scrapling.parser import Selector

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

异步会话示例

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 with AsyncStealthySession(max_pages=2) as session:
    tasks = []
    urls = ['https://example.com/page1', 'https://example.com/page2']

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

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

CLI 与交互式 Shell

Scrapling 自带命令行入口(pyproject.toml 注册了 scraplingscrapling-mcp 两个可执行命令,实现位于 cli.py),完整命令说明见 docs/cli/overview.md

启动交互式抓取 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

extract get 走纯 HTTP 引擎,extract fetch 走浏览器自动化引擎,extract stealthy-fetch 走隐身引擎并可加 --solve-cloudflare 过 Cloudflare 验证,--css-selector 可把提取范围限定到指定选择器。

性能基准

文档内置两组基准数据(均为 100 次以上运行的平均值,方法论见 benchmarks.py)。

文本提取速度(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

安装与环境要求

Scrapling 要求 Python 3.10 及以上pyproject.tomlrequires-python = ">=3.10"),基础安装:

pip install scrapling

需要注意官方给出的重要提示:默认安装只包含解析引擎及其依赖,不包含 fetchers 与 CLI 依赖。因此若像上文示例那样导入 scrapling.fetchersscrapling.spiders,在仅安装基础包的环境下会抛出 ModuleNotFoundError。从 pyproject.toml 可确认基础依赖仅有 lxmlcssselectorjsontldw3libtyping_extensions,而 curl_cffiplaywrightpatchright 等抓取依赖全部位于 fetchers 可选组中。

抓取与浏览器依赖(使用任何 Fetcher/Spider 功能前必须执行):

pip install "scrapling[fetchers]"

scrapling install           # 正常安装浏览器及系统依赖
scrapling install  --force   # 强制重新安装

scrapling install 会下载全部浏览器、系统依赖与指纹处理依赖。也可以从代码中安装而不走命令行:

from scrapling.cli import install

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

其他可选扩展

pip install "scrapling[ai]"      # MCP 服务器功能
pip install "scrapling[shell]"   # 交互式 Shell 与 extract 命令
pip install "scrapling[all]"     # 全部功能

安装任一扩展后,若尚未执行过,仍需运行 scrapling install 补齐浏览器依赖。

Docker:官方镜像包含全部扩展与浏览器,从 DockerHub 或 GitHub 容器注册表拉取:

docker pull pyd4vinci/scrapling
# 或
docker pull ghcr.io/d4vinci/scrapling:latest

该镜像基于仓库主分支由 CI 自动构建发布,构建配置见 Dockerfile

合规声明、引用与许可

文档中的法律声明值得抓取实践者留意:本库仅提供用于教育与研究目的;使用者须遵守当地及国际数据抓取与隐私法律;作者与贡献者不对软件的不当使用承担责任;应始终尊重目标网站的条款与 robots.txt 文件。这与 Spider 框架内置的 robots_txt_obey 合规开关(robotstxt.py)形成呼应。

若将 Scrapling 用于学术研究,文档建议采用如下引用:

@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),文档致谢部分说明其 translator 模块 改编自 Parsel(BSD 许可)。贡献规范见 CONTRIBUTING.md

小结

Scrapling 将“请求—解析—爬取”三个层级的能力整合进单一库:解析层通过 adaptive/auto_save 机制让选择器在页面改版后自动重定位;抓取层提供纯 HTTP、标准浏览器、隐身浏览器三档引擎并统一了同步/异步与会话/一次性四种使用形态;爬取层以 Scrapy 风格 API 提供了并发、多会话路由、AutoThrottle、断点续传与模板库。结合本文给出的源码文件位置,读者可从 spider.pyparser.pyfetchers/init.py 出发,继续深入任意一层的具体实现。

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

项目优选

收起
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