Адаптивные селекторы нередко приписывают не тем инструментам. Половина сравнений скраперов, которые я читаю, ставит отметку «переживает редизайн сайта» каким-нибудь крупным AI-краулерам, которые на деле этого не умеют. Python-библиотека, которая делает эту функцию центральной, — это Scrapling, быстро растущий проект с примерно 68,7 тыс. звёзд на GitHub по состоянию на 2026-07-09.
Поэтому я провёл именно тот тест, который важен для такого заявления. Я собрал тестовую страницу, сохранил селектор, а затем переименовал класс целевого элемента — ровно тот сценарий, из-за которого скрапер молча начинает возвращать пустоту на следующее утро после редизайна. Обычный селектор вернул пустой результат. Адаптивный матч Scrapling всё равно нашёл элемент. Эта часть — правда, и ниже я покажу цифры. Но почти никто не измеряет, где восстановление заканчивается, и именно эта граница в итоге и делает весь обзор.
Что такое Scrapling на самом деле

Scrapling позиционирует себя как адаптивный фреймворк для веб-скрейпинга, который справляется «со всем — от одиночного запроса до полноценного краула». Если убрать маркетинговую обёртку, внутри два уровня: HTTP Fetcher, который забирает страницы, и Selector на базе lxml, который их парсит, с полноценной поддержкой CSS/XPath и удобными псевдоселекторами ::text и ::attr(). Лицензия — BSD-3-Clause, то есть одна из самых свободных и дружелюбных к коммерческому использованию. Я тестировал версию 0.4.10 — актуальный релиз на тот момент, так что оговорка «вы бенчмаркили что-то устаревшее» здесь не нужна.
Самый интересный слой — это адаптивный механизм поверх парсера. Представьте, как работает обычный селектор: это жёстко заданный адрес. «Возьми элемент с классом product-name». Переименуйте класс — и адрес указывает в пустоту. Scrapling же может сохранить отпечаток элемента при первом запуске, а потом, когда разметка поменяется, найти тот же элемент по этому отпечатку, а не по уже недействующему адресу. Согласно документации Scrapling по adaptive scraping, этап сопоставления оценивает сходство по тегу элемента, тексту, атрибутам, соседям и позиции — без участия модели, только структурное сравнение с тем, что было сохранено.
Важно честно сказать и про происхождение функции, потому что от этого зависит, как вы читаете обзор. Адаптивное восстановление — это реальная, задокументированная возможность, а не моя находка: вендорская документация подробно описывает механизм сохранения в SQLite и поиска по сходству, и независимые обзоры сторонних авторов тоже разбирают его пошагово. Сама идея self-healing selectors вообще появилась раньше Scrapling в мире тестовой автоматизации. Уникальность здесь в том, что Scrapling поставляет это как встроенную функцию библиотеки: обычные парсеры вроде lxml, parsel и BeautifulSoup дают статические селекторы и ничего сами не «переназначают». Так что это отличительная, но документированная функция, которую я воспроизвёл и нагрузил тестами — а не нечто, чего нет ни у кого.
Подробно о тесте адаптации

Вот как выглядела проверка. Я поднял тестовый каталог и отслеживал элемент товара, пока у него был класс product-name. Затем я переименовал этот класс в product-title и снова запустил тот же код. Обычный селектор .product-name нашёл 0 элементов — именно такой пустой результат и ожидаешь, когда селектор указывает на класс, которого больше нет. Адаптивное повторное сопоставление Scrapling восстановило отслеживаемый элемент, используя отпечаток, сохранённый по предыдущей версии страницы. Сырый результат лежит в репозитории бенчмарка: local_adaptive_selector.json.

Попробуйте Thunderbit для извлечения веб-данных

А теперь та часть, которую большинство обзоров пропускает. Я пошёл дальше и добавил синтетический тест с несколькими элементами — три отслеживаемых элемента вместо одного. Scrapling восстановил только первый сохранённый элемент, а не все три. Это не провал и не баг; в документации авто-сопоставление описано как отслеживание элемента, по одному отпечатку на каждый сохранённый элемент, так что результат 1 из 3 при настройках по умолчанию — это поведение именно по задумке. Но из этого следует важная оговорка: корректнее говорить «устойчивое отслеживание элементов», а не «автоматическое восстановление всей страницы после редизайна». Auto-match следует за тем элементом, который вы ему указали. Устойчивость для нескольких элементов — это уже настройка, которую вы делаете сами.
Это различие гораздо важнее, чем кажется сначала. «Переживает изменения разметки» — это заголовок. «Продолжает отслеживать один отпечатанный элемент при изменениях разметки, а всё остальное настраиваете вы» — это реальная функция, за которую вы платите вниманием. Ожидайте первого — и будете разочарованы. Ожидайте второго — и инструмент спокойно делает свою работу.
Настройка: неудобство, о котором никто не предупреждает
На это я потратил реальное время, так что предупреждаю вас заранее. pip install scrapling ставит парсер — и только парсер. Как только я написал from scrapling.fetchers import Fetcher, всё сломалось цепочкой отсутствующих зависимостей: сначала curl_cffi, потом playwright, потом browserforge, и каждая следующая ошибка появлялась только после того, как я устранял предыдущую.
Решение — ставить дополнительный пакет: pip install "scrapling[fetchers]", либо запускать CLI-команду scrapling install, которая подтягивает полный стек HTTP- и browser-fetcher’ов. После этого всё заработало. Но сценарий «базовая установка выглядит нормально, а на первом fetch всё падает» — реален, и в лоб об этом никто сразу не говорит. Сразу закладывайте [fetchers] extra и его тяжёлые транзитивные зависимости с первой же команды — и избавите себя от этого обходного пути.
Что выдержало обычное HTTP-извлечение
Когда fetcher’ы были на месте, обычный путь извлечения работал стабильно — recall 1.0 по всем проверкам:
| Тест | Результат |
|---|---|
| Статический каталог + пагинация | 12/12 товаров |
| Извлечение статьи | заголовок + 3/3 абзаца |
| Динамический JSON API | 8/8 элементов |
| Books to Scrape (публичный) | 20 товаров |
| Обработка HTTP 500 | статус показан, без падения |
Здесь хорошо видно влияние lxml. CSS и XPath ведут себя именно так, как и хочется, а псевдоселекторы ::text и ::attr() делают код коротким и читаемым, вместо того чтобы превращать его в кашу из вложенных вызовов. Случай с 500 — небольшой, но показательный: Fetcher не упал с traceback, а явно отдал статус. Это и есть разница между скрапером, который можно поставить по расписанию, и тем, за которым придётся присматривать вручную. Полные числа лежат в scrapling-test-summary.json.
Ничего эффектного. Просто корректно. А корректность сильно недооценивают.
Что он не умеет (и это сделано специально)

HTTP Fetcher не рендерит JavaScript. Я направил его на fixture с JS-рендерингом и получил 0 карточек; тот же 0 был на публичной странице Quotes to Scrape JS. Это не дефект — HTTP Fetcher скачивает HTML, он не запускает браузер, поэтому клиентский контент просто не существует на момент парсинга. У Scrapling есть отдельный DynamicFetcher на базе браузера для JS-страниц. В этом проходе я его не тестировал, поэтому не буду делать вид, что знаю, как он работает. Просто не направляйте HTTP-путь на приложение с клиентским рендерингом и не ждите, что там уже будет контент.
Есть ещё StealthyFetcher, ориентированный на антидетект. Я рассматриваю это исключительно как вопрос комплаенса — и точка. Где и как вам разрешено скрапить, зависит от вас и вашей правовой позиции, а в этом обзоре тестировались возможности извлечения, а не обхода защит. Я его не запускал и не оцениваю.
Плюсы и минусы
Плюсы:
- Адаптивные селекторы действительно восстановили отслеживаемый элемент после переименования класса, тогда как обычный селектор вернул 0 — именно ради этого Scrapling и выбирают.
- Извлечение по HTTP на статических страницах, статьях и JSON API показало recall 1.0.
- Чистая связка lxml с CSS/XPath и удобные псевдоселекторы
::text/::attr(). - Корректная обработка HTTP 500 — статус виден, падения нет.
- Тестируемая версия совпала с актуальным релизом, без расхождения по версиям.
- Разрешающая лицензия BSD-3-Clause, подходящая для коммерческого использования.
Минусы:
- Auto-match отслеживает один сохранённый элемент, а не всю страницу — в тесте с тремя элементами восстановился один. Формулируйте ожидания соответственно.
pip install scraplingставит только парсер; для fetcher’ов нужен extra[fetchers]и его тяжёлая цепочка зависимостей, о которой я узнал на практике.- HTTP Fetcher не рендерит JavaScript; для клиентского контента нужен браузерный
DynamicFetcher, который здесь не тестировался. - Флагманская функция устойчивости требует ручной настройки для сценариев с несколькими элементами.
Кому это подойдёт, а кому лучше пройти мимо
Scrapling стоит вашего внимания, если вы поддерживаете скраперы для сайтов, которые часто меняют дизайн, и устали от того, что одно переименование класса тихо убивает сбор данных на следующий день. Если ваша постоянная боль звучит как «селекторы ломаются каждые пару недель, а я просто хочу, чтобы нужный элемент продолжал находиться», то это как раз ваш случай. Даже если вы никогда не включите адаптивный слой, библиотека остаётся удобным и лёгким lxml-экстрактором для статических страниц и JSON API.
Но в двух случаях ожидания лучше скорректировать или поискать другой инструмент. Если вы надеетесь, что адаптивные селекторы автоматически починят всю страницу после редизайна, — они отслеживают элементы, а не пересобирают макеты. И если ваши цели сильно завязаны на JavaScript, а вы не хотите поднимать браузерный DynamicFetcher, одного HTTP-пути вам не хватит. В любом случае, если всё-таки ставите Scrapling, добавляйте extra [fetchers] с самой первой команды.
Где здесь место управляемому AI scraping API
Scrapling — это бесплатная open-source библиотека, которую вы запускаете и обслуживаете сами. Вы контролируете код, цепочку зависимостей и настройку — а взамен не платите за каждый запрос и держите всё у себя. Это вполне осознанный и рабочий выбор, и для многих команд он действительно лучший.
Но есть более важный вопрос: кто отвечает за устойчивость? У Scrapling ответ такой — вы. Вы сами делаете отпечатки элементов и настраиваете отслеживание. У управляемого AI scraping API ответ другой: обработка изменений переносится на сервер. Именно эту нишу для технических команд закрывает стек разработчика Thunderbit. POST /extract возвращает структурированный JSON по схеме JSON Schema, которую вы задаёте сами, а рендеринг, антибот-защита и изменения разметки обрабатываются на стороне сервера; флаг renderMode управляет тем, сколько страницы будет выполнено до извлечения. Для AI-агентов и кодовых ассистентов есть MCP-сервер Thunderbit — thunderbit_suggest_fields бесплатен и запускается первым, чтобы спланировать извлечение — а также CLI через npx @thunderbit/thunderbit-cli для терминала, скриптов и CI. Один и тот же AI-движок лежит в основе всех трёх интерфейсов.
Реальный выбор здесь не «лучше или хуже», а «где должна жить логика устойчивости». В Scrapling вы держите её у себя: сами отпечатки, сами настройки, нулевая стоимость за вызов, но и вся связанная поддержка тоже на вас. С управляемым API вы отдаёте обработку дрейфа на сторону сервиса и платите за запросы. Небольшой проект, self-hosted, и вам нравится самим управлять настройкой? Тогда контроль Scrapling — правильный вариант. Нужно масштабироваться на сотни сайтов и не хочется вручную присматривать за отпечатками селекторов на каждом из них? Управляемый подход убирает именно этот класс поддержки.
Если сравниваете решения в этой категории, полный open-source бенчмарк скраперов сопоставляет Scrapling с другими на одних и тех же тестовых страницах, а обзор Scrapy и обзор Colly покрывают ещё два HTTP-first фреймворка, которые тоже стоит посмотреть.
Итог
Стоит ли использовать Scrapling? Да — если вам нужен open-source Python-экстрактор, чья главная фишка заключается в том, чтобы продолжать находить отслеживаемый элемент даже после того, как разметка под ним изменилась, и вы понимаете реальные границы этой фишки. Он восстановил элемент там, где сломанный селектор уже ничего не нашёл, на переименовании, которое у обычного скрапера молча отняло бы данные. Обычное HTTP-извлечение аккуратное и показало полный recall на всех тестовых сценариях. Лицензия свободная, а версия, которую я тестировал, была актуальной.
Просто правильно оценивайте обещание — и инструмент вас порадует. Он отслеживает элементы, а не автоматически перестраивает страницы: в тесте с тремя элементами восстановился один. Устанавливайте extra [fetchers] сразу, иначе упрётесь в стену зависимостей, как я. И если вашим страницам нужен JavaScript, это задача браузерного fetcher’а, а не HTTP-режима. В этих рамках Scrapling делает именно то, чем известен, и среди Python-библиотек для скрейпинга это один из немногих инструментов, которые действительно поставляют ту самую функцию, которую все постоянно приписывают другим.
Попробуйте Thunderbit для извлечения веб-данных Get Started Free
Часто задаваемые вопросы
Действительно ли адаптивные селекторы Scrapling переживают редизайн сайта?
Да, если речь о переименовании класса у отслеживаемого элемента — это подтверждено тестом. После того как я переименовал product-name в product-title, обычный селектор вернул 0, а адаптивное повторное сопоставление восстановило отслеживаемый элемент. Но библиотека отслеживает сохранённые элементы, а не пересобирает всю страницу: в синтетическом тесте с тремя элементами восстановился один. Воспринимайте это как устойчивое отслеживание элементов, а не автоматическое восстановление всей страницы.
Почему pip install scrapling ломается при импорте fetcher’а?
Потому что базовая установка ставит только парсер. При импорте scrapling.fetchers начинается цепочка отсутствующих зависимостей — curl_cffi, затем playwright, затем browserforge. Используйте pip install "scrapling[fetchers]" (или CLI-команду scrapling install), чтобы подтянуть полный стек fetcher’ов, и импорт заработает.
Может ли Scrapling скрапить страницы, отрендеренные JavaScript?
Не с HTTP Fetcher — он вернул 0 и на JS-fixture, и на публичной странице Quotes JS, потому что скачивает HTML без запуска браузера. У Scrapling есть отдельный браузерный DynamicFetcher для JS-страниц, который в этом тесте не проверялся, поэтому о его производительности я пока ничего не скажу.
Быстрый ли и точный ли Scrapling для обычного извлечения? В тестах он был точным — recall 1.0 на статических каталогах, страницах статей и JSON API, плюс чистая работа CSS/XPath на базе lxml. Он также корректно обработал HTTP 500, показав статус вместо падения. Если вы вообще не трогаете адаптивный слой, это всё равно сильный и лёгкий инструмент для статического контента.
Можно ли использовать Scrapling в коммерческих проектах бесплатно? Да, лицензия BSD-3-Clause — свободная и коммерчески дружелюбная. Как всегда, перед использованием проверьте актуальную лицензию в репозитории.


