> · 8 мин

Scrapling — Python-фреймворк, который парсит сайты с Cloudflare и не ломается при редизайне

Scrapling — Python-фреймворк, который парсит сайты с Cloudflare и не ломается при редизайне

Scrapling — Python-фреймворк, который парсит сайты с Cloudflare и не ломается при редизайне

Каждый, кто писал скраперы, знает эту боль: ты потратил вечер на CSS-селекторы, скрипт работает неделю — а потом сайт меняет один div, и всё рассыпается. А если на сайте ещё и Cloudflare — вообще капут.

Scrapling решает обе проблемы одним pip install. Это Python-фреймворк с 31K+ звёздами на GitHub, который умеет три вещи, за которые раньше приходилось собирать стек из 4-5 библиотек: адаптивный трекинг элементов (селекторы не ломаются при редизайне), обход Cloudflare Turnstile из коробки, и полноценный spider framework в стиле Scrapy.

TL;DR: Scrapling — один фреймворк вместо BeautifulSoup + Playwright + curl-cffi + Scrapy. Адаптивные селекторы переживают редизайн, StealthyFetcher обходит Cloudflare Turnstile автоматически, а MCP-сервер позволяет Claude парсить сайты за тебя. Python 3.10+, 31K+ stars, 92% покрытие тестами.

Зачем ещё один фреймворк для скрапинга

Если посмотреть на типичный стек веб-скрапера в 2026 году, он выглядит так: requests или httpx для простых запросов, BeautifulSoup или parsel для парсинга HTML, Playwright или Selenium для JavaScript-heavy страниц, curl-cffi или httpcloak для TLS-имперсонации, Scrapy для краулинга, плюс capsolver или ручной обход CAPTCHA.

Scrapling сжимает всё это в один пакет. Но не просто "ещё один враппер" — у него есть фича, которой нет больше ни у кого: adaptive element tracking. Фреймворк запоминает "отпечатки" DOM-элементов и находит их даже после того, как сайт полностью переделал вёрстку.

Установка за 2 минуты

# Базовый парсер (без браузеров)
pip install scrapling

# С поддержкой всех fetcher-ов (HTTP, stealth, browser)
pip install "scrapling[fetchers]"
scrapling install

# Полная установка (включая MCP-сервер и shell)
pip install "scrapling[all]"
scrapling install

Команда scrapling install скачивает и настраивает браузеры для StealthyFetcher и DynamicFetcher. Если не хочешь возиться — есть Docker-образ с браузерами из коробки:

docker pull pyd4vinci/scrapling

Требования: Python 3.10+. На более старых версиях не заведётся.

Три способа достать данные с любого сайта

Scrapling предлагает три "фетчера" — каждый для своего уровня защиты.

1. Fetcher — быстрый HTTP с TLS-имперсонацией

Для сайтов без серьёзной защиты. Под капотом curl-cffi — подделывает TLS-отпечаток Chrome или Firefox, поддерживает HTTP/2 и HTTP/3:

from scrapling.fetchers import Fetcher

# Один запрос — имперсонируем Chrome
page = Fetcher.fetch(
    "https://quotes.toscrape.com/",
    impersonate="chrome"
)
quotes = page.css(".quote .text::text").getall()
print(quotes)  # ['The world as we...', 'It is our choices...', ...]

Работает как requests, только сервер видит "настоящий" Chrome вместо Python-бота. Для большинства сайтов без Cloudflare — этого достаточно.

2. StealthyFetcher — обход Cloudflare Turnstile

Когда на сайте Cloudflare challenge или Turnstile — StealthyFetcher запускает stealth-браузер с fingerprint spoofing:

from scrapling.fetchers import StealthyFetcher

# Автоматически решает Cloudflare Turnstile
page = StealthyFetcher.fetch(
    "https://protected-site.com/",
    headless=True,
    network_idle=True
)
data = page.css("h1::text").get()

В v0.4.1 скорость решения Cloudflare challenge удвоилась — по заявлению автора, оптимизировали regex для детекции и убрали лишний JavaScript при stealth-сессии.

3. DynamicFetcher — полный браузер через Playwright

Для сайтов с тяжёлым JavaScript, SPA или когда нужно кликать кнопки:

from scrapling.fetchers import DynamicFetcher

page = DynamicFetcher.fetch(
    "https://spa-app.com/",
    headless=True,
    network_idle=True,
    page_action=lambda page: page.click("button.load-more")
)
items = page.css(".item-card").getall()

DynamicFetcher — это Playwright Chromium с удобной обёрткой. Можно передать page_action — лямбду с любыми действиями на странице.

Adaptive tracking — фича, ради которой стоит попробовать

Представь: ты парсишь цены с интернет-магазина по селектору .product-price. Через неделю магазин переезжает на новый фреймворк, и класс становится .price-tag-new. У тебя всё ломается.

Scrapling запоминает "отпечаток" элемента — не только CSS-класс, а контекст: соседние элементы, позицию в DOM, текстовое содержимое. И при следующем запуске находит тот же элемент, даже если класс изменился:

from scrapling.fetchers import Fetcher

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

# Первый запуск: сохраняем "отпечатки" элементов
prices = page.css(".product-price", auto_save=True)

# ...сайт обновился, класс изменился...

# Следующий запуск: Scrapling ищет по отпечатку
page = Fetcher.fetch("https://shop.example.com/")
prices = page.css(".product-price", adaptive=True)
# Находит элементы, даже если класс теперь .price-tag-new

Это не магия — Scrapling использует алгоритмы similarity matching по структуре DOM. Работает не всегда (если сайт полностью перестроил структуру страницы — не поможет), но для типичных редизайнов — спасение.

Spider framework — краулинг как в Scrapy

В v0.4 появился полноценный async spider с Scrapy-подобным API. Пример: краулим сайт с цитатами, используя обычный HTTP для публичных страниц и stealth-браузер для защищённых:

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

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

    def configure_sessions(self, manager):
        manager.add("fast", FetcherSession(impersonate="chrome"))
        manager.add("stealth", AsyncStealthySession(headless=True))

    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("li.next a::attr(href)").get()
        if next_page:
            yield Request(next_page)

# Запуск
result = QuoteSpider().run()
result.items.to_json("quotes.json")

Что тут есть из коробки:

  • Multi-session routingsid="stealth" отправит запрос через stealth-браузер, остальные идут через быстрый HTTP
  • Pause/resume — передай crawldir="./checkpoints", и при Ctrl+C прогресс сохранится
  • Streamingasync for item in spider.stream() для обработки в реальном времени
  • Proxy rotation — встроенный ProxyRotator с циклической и кастомной ротацией

MCP-сервер — пусть Claude парсит за тебя

Scrapling можно подключить как MCP-сервер к Claude Code, Cursor или VS Code Copilot:

pip install "scrapling[ai]"

MCP-сервер предварительно извлекает контент со страницы перед отправкой в LLM — это экономит токены. Вместо того чтобы скормить Claude весь HTML (который может быть 500KB+), Scrapling отдаёт только нужные данные.

Для Claude Code это значит: ты можешь написать "спарси цены с сайта X" — и агент сам использует Scrapling для извлечения данных, не тратя контекстное окно на сырой HTML.

Подводные камни

Cloudflare Turnstile — да, enterprise-grade защита — нет. StealthyFetcher уверенно проходит Cloudflare Turnstile и Interstitial challenge. Но DataDome, Akamai Bot Manager и PerimeterX — совсем другая история. В обсуждениях на GitHub пользователи жалуются на проблемы с DataDome и Quora (которая использует усиленный Cloudflare). Если твой целевой сайт за enterprise-антиботом — скорее всего, понадобится платный сервис вроде ZenRows или Bright Data.

Breaking changes в v0.4 — и это больно. Из StealthyFetcher убрали аргументы block_images, humanize, addons, os_randomize, disable_ads и geoip. Автор объяснил, что каждый из них "имел свои проблемы в Chromium". Также удалили методы css_first/xpath_first — теперь нужно использовать bracket notation [0]. Если у тебя были скрипты на v0.3 — готовься к рефакторингу.

Нет перехвата сетевых запросов браузера. Issue #159 просит добавить слушатель запросов/ответов в browser fetchers — пока этого нет. Если тебе нужно перехватывать API-вызовы, которые делает SPA — придётся использовать Playwright напрямую.

Python 3.10+ обязателен. Если ты на 3.8 или 3.9 — не заведётся. А scrapling install скачивает ~300MB браузеров при первом запуске, что на слабом CI может быть проблемой. Docker-образ решает эту проблему, но весит прилично.

Альтернативы

  • Crawl4AI — 62K+ stars, заточен под AI-пайплайны. Отдаёт чистый Markdown или structured JSON, async browser pools, но нет adaptive tracking и anti-bot из коробки слабее. Лучший выбор если тебе нужно просто скормить сайт в LLM.

  • Crawlee — от Apify, есть на Python и JS. Промышленный краулер с request queuing, session rotation, exponential backoff. Нет встроенного anti-bot bypass — предполагается, что ты используешь Apify Cloud или свои прокси. Выбирай, если нужен надёжный краулинг миллионов страниц.

  • Firecrawl — 70K+ stars, managed API. Отправляешь URL — получаешь чистый Markdown. Ноль настройки, ноль инфраструктуры, но платный для серьёзных объёмов (free tier ограничен). Идеален для быстрого прототипа или если не хочешь поддерживать свой скрапер.

Вердикт

Scrapling — самый полный open-source Python-фреймворк для скрапинга в 2026 году. Если ты пишешь парсеры регулярно и устал от поломок при редизайне — adaptive tracking реально экономит часы. Обход Cloudflare Turnstile работает из коробки, spider framework покрывает 90% задач краулинга.

Не стоит выбирать Scrapling, если тебе нужен enterprise-grade anti-bot (DataDome, Akamai) — тогда дешевле взять ZenRows или Bright Data. И если ты просто хочешь скормить один сайт в LLM без возни — Firecrawl сделает это за один API-вызов.

Как попробовать

  1. Установи с fetcher-ами:
pip install "scrapling[all]"
scrapling install
  1. Попробуй простой парсинг:
from scrapling.fetchers import Fetcher
page = Fetcher.fetch("https://quotes.toscrape.com/", impersonate="chrome")
print(page.css(".quote .text::text").getall())
  1. Проверь stealth на защищённом сайте:
from scrapling.fetchers import StealthyFetcher
page = StealthyFetcher.fetch("https://nowsecure.nl/", headless=True)
print(page.css("h1::text").get())
  1. Подключи MCP-сервер для Claude Code — установи pip install "scrapling[ai]" и добавь в конфиг MCP-серверов

  2. Документация: scrapling.readthedocs.io

$ ls ./related/

Похожие статьи

subscribe.sh

$ cat /dev/blog/updates

> Свежие заметки о программировании,

> DevOps и AI — прямо в мессенджер

./subscribe