Scrapy часто относят к инструментам, которые «не тянут современные сайты», потому что он не запускает JavaScript. Но это как раз перевёрнутое понимание. Смысл Scrapy как раз в том, чтобы не рендерить страницу, и как только видишь это в работе, отсутствие браузера уже не кажется минусом.
Я убедился в этом на практике буквально за один прогон. Собрал тестовый каталог с JavaScript-рендерингом, направил на него Scrapy так, как это сделал бы браузер, — и получил 0 карточек товара. Потом отправил того же паука в JSON-эндпоинт, к которому страница тихо обращалась в фоне, и получил 8/8 элементов, без мусора и искажений. Один и тот же инструмент, одна и та же сессия — и совершенно разные результаты. Именно этот разрыв и есть главная тема обзора.
Что такое Scrapy на самом деле — и чем он не является

Scrapy — это Python-фреймворк для обхода сайтов и извлечения структурированных данных. Именно так его описывают сами разработчики в документации, и после практики понимаю: описание точное, без маркетинговых преувеличений. Проект достаточно зрелый и известный, чтобы быть первым ответом на вопрос «чем серьёзные Python-разработчики собирают данные?». И цифры это подтверждают: примерно 62 981 звезда на GitHub по состоянию на 2026-07-07 (scrapy/scrapy), 11 773 форка и 590 открытых issue на ту же дату. Лицензия BSD-3-Clause, Python 3.10 или новее, а версия, которую я тестировал, — 2.17.0; она как раз вышла утром в день моих проверок, так что здесь без оговорок «на старой версии».
Вот главное отличие от более новых AI-краулеров: по умолчанию Scrapy работает только по HTTP. Без браузера. Без движка рендера. Он получает HTML по сети, передаёт его парсеру и даёт тебе вытащить поля через CSS-селекторы или XPath. Назвать это ограничением можно лишь наполовину: такая формулировка упускает саму идею. Scrapy исходит из того, что запускать headless Chrome ради обычного парсинга — часто не лучшая стратегия; умнее сначала найти запрос к данным, который уже делает страница, и обращаться прямо к нему.
Это не моя трактовка инструмента, а его официальный принцип. В документации по динамическому контенту сказано прямо: сначала ищи и воспроизводи исходный запрос к данным, а к headless-браузеру прибегай только если без этого никак. Большинство скраперов первым делом открывают браузер и даже не думают об API. Scrapy меняет этот порядок по умолчанию.
Ключевые функции и логика, стоящая за ними
Внутри Scrapy — набор компонентов, и все они исходят из одного: ты не пользователь «в один клик», а разработчик, которому нужен контроль.
Пауки (Spiders). Ты пишешь класс, задаёшь стартовые URL и определяешь callback parse, который возвращает элементы или переходит по ссылкам дальше. Это больше кода, чем у no-code экстрактора, — правила извлечения пишешь ты сам. Зато ты точно управляешь тем, что именно собрать и куда двигаться дальше.
Селекторы. Разбор страниц построен на parsel, а под ним — lxml. И CSS, и XPath здесь — полноценные инструменты, а не добавка сверху. Благодаря lxml выборка остаётся быстрой, а код извлечения читается как намерение, а не как клубок операций со строками.
Экспорт данных. Если направить паука в файл, Scrapy сам сохранит результаты в JSON, JSON Lines, CSV или XML — без дополнительной обвязки. В моём тесте один паук для статического каталога сохранил и JSON, и CSV без единой строки кода под экспорт. История с feed export здесь полностью соответствует реальности.
AutoThrottle и управление обходом. Запросы ставятся в очередь асинхронно через Twisted, а ты получаешь лимиты конкуррентности, задержки загрузки, ограничения по глубине, AutoThrottle для адаптивного rate limiting и уважение к robots.txt. Именно эти механизмы не дают большому обходу превратиться в атаку на сервер.
Только HTTP — и это тоже достоинство. Отсутствие браузера означает низкое потребление памяти, высокую пропускную способность и отсутствие движка рендера, который нужно обслуживать — при условии, что нужные данные доступны по обычному HTTP. А это, чаще чем думают сторонники browser-first подхода, именно так.
Установка: стек зависимостей, который обычно никто не показывает

Установка прошла без происшествий, и для такого крупного фреймворка это само по себе стоит отметить. Команда pip install Scrapy==2.17.0 отработала чисто в новом виртуальном окружении на macOS arm64: бинарные колёса подтянулись, ничего не собиралось вручную и не падало на компиляции. Собственно, и хорошо — это как раз тот случай, когда отсутствие драмы и есть хорошая новость.
Но посмотри, что именно подтянулось вместе с пакетом. Команда scrapy version -v показала Scrapy 2.17.0 поверх lxml 6.1.1, Twisted 26.4.0, pyOpenSSL 26.3.0 и cryptography 49.0.0, а также parsel, cssselect и tldextract. Это уже серьёзный след — настоящий фреймворк для краулинга, а не просто один HTML-парсер. На этой машине под всё нашлись колёса, так что установка прошла без боли. Но в других окружениях официальная документация всё ещё предупреждает о платформенных нюансах, и чаще всего проблемы возникают на участке cryptography и Twisted, так что если у тебя нестандартная система, это стоит закладывать заранее. В моём случае всё прошло гладко, но размер устанавливаемого стека всё равно полезно понимать до старта: ты ставишь фреймворк, а фреймворк и весит как фреймворк.
Практика: что сработало без нареканий

После установки всё, что касалось статических страниц, отработало ровно. Полное извлечение без потерь.
| Тест | Результат | Время |
|---|---|---|
| Локальный статический каталог + пагинация | 12/12 товаров | 0.557s |
| Экспорт CSV из статического каталога | записано 12 строк | (тот же прогон) |
| Извлечение статьи | заголовок + 3/3 абзаца | 0.416s |
| Граф обхода, DEPTH_LIMIT=2 | 11 страниц на глубинах 0/1/2 | 0.904s |
| Локальная страница 500 | статус 500 получен, без падения | 0.424s |
| Books to Scrape (публичный) | 20 товаров | 2.053s |
| Quotes to Scrape spider (публичный) | 12 цитат | 3.465s |
Паук для статического каталога прошёл пагинацию с первой страницы на вторую и собрал 12/12 ожидаемых записей, после чего в том же проходе сохранил данные и в JSON, и в CSV. Отдельно стоит задержаться на тесте со статьёй. Scrapy не пытался автоматически превращать страницу в аккуратный Markdown — вместо этого я явно указал селекторы для полей article, а навигацию и футер вынес в отдельные поля. В результате получил 3/3 абзаца основного текста, а служебные блоки остались изолированы, а не смешались с контентом. В этом и есть компромисс: ты сам пишешь селекторы, зато получаешь ровно то, что запросил, и ничего лишнего.
Управление обходом на небольшом масштабе тоже показало себя нормально. При DEPTH_LIMIT=2, небольшой задержке загрузки, ограничении конкуррентности на домен и включённом robots.txt граф обхода прошёл 11 страниц по глубинам 0, 1 и 2, и глубина считалась корректно. Обработка ошибок была такой же спокойной. Намеренно возвращённая страница 500 пришла как структурированный объект, а статус 500 был поднят через handle_httpstatus_list — без исключения, без обрыва выполнения. Scrapy воспринимает ошибочный статус как то, что нужно обработать внутри логики паука, а не как сюрприз, который валит весь обход.
Практика: JavaScript-стена и дверь рядом с ней

Теперь — тот самый результат, вокруг которого и строится этот обзор.
Я направил HTTP-загрузчик Scrapy на тестовый каталог, отрисовываемый JavaScript. Он скачал исходный HTML, не нашёл 0 узлов .product-card и пошёл дальше — потому что скрипт, который должен был отрисовать эти карточки, он не запускал. Публичная страница Quotes to Scrape JS показала ту же картину: 0 отрендеренных узлов с цитатами. На этом тесте легко было бы списать Scrapy со счетов как бесполезный для задач этого десятилетия.
Но останавливаться на этом нельзя. Этот JS-каталог наполнялся через JSON API в фоне — как это и бывает у большинства подобных страниц. Я направил того же паука в этот эндпоинт и получил 8/8 товаров за 0.416s — без браузера, без рендера, просто запрос к URL, к которому страница уже обращалась, и разбор ответа JSON.
Именно здесь в миниатюре видна философия «повтори запрос». Отрисованная страница — это приманка; данные всё время лежали за API, а дизайн Scrapy подталкивает тебя обращаться именно туда, а не платить за headless-браузер только ради того, чтобы он наблюдал, как страница собирается по кусочкам. Это быстрее, легче и менее ломко: контракт API обычно стабильнее, чем DOM, собранный на клиенте. Но есть и минус: всё нужно делать вручную. Нужно открыть Network, найти запрос и самому воспроизвести заголовки и параметры. Scrapy не найдёт API за тебя — он лишь делает обращение к нему максимально простым, когда ты уже знаешь, куда идти.
Два ограничения — без прикрас. Если под капотом действительно нет запроса, который можно воспроизвести, а данные формируются только на клиенте и API отсутствует, тогда Scrapy нужен headless-браузер через дополнительную интеграцию, которую ты подключаешь сам; в этом прогоне я этот путь не тестировал. И всё выше я запускал на небольших тестовых наборах и публичных демо-страницах. Я не делал краулинг на 100–1000 страниц, поэтому не утверждаю ничего о памяти, пропускной способности или поведении retries на масштабе — асинхронное ядро и механизмы обхода дают хорошие основания для доверия, но это всё же сигнал, а не измерение.
Плюсы и минусы
Плюсы:
- HTTP-only архитектура быстрая и лёгкая — 12/12 на статике примерно за полсекунды, 8/8 из JSON API за 0.416s, без накладных расходов браузера.
- Подход с повтором запроса действительно работает: JavaScript-страница, которая вернула 0, отдала все 8 элементов через свой API.
- CSS- и XPath-селекторы на базе
lxmlделают код извлечения понятным и быстрым. - Экспорт в JSON/CSV/XML работает из коробки, без отдельного кода под выгрузку.
- Явная обработка ошибок: статус 500 приходит как статус, который ты ловишь, а не как падение процесса.
- Зрелые механизмы обхода: конкуррентность, задержки, лимиты глубины, AutoThrottle, robots.txt.
- Лицензия BSD-3-Clause, удобная и для коммерческого использования; на современной машине установка прошла чисто.
Минусы:
- По замыслу не рендерит JavaScript — на клиент-рендеренной странице будет 0 узлов, пока ты сам не найдёшь API.
- Найти исходный запрос нужно вручную; Scrapy не подскажет тебе эндпоинт.
- Стек зависимостей довольно тяжёлый (
Twisted,lxml,cryptography,pyOpenSSL,parsel,tldextract) — здесь всё было нормально, но на необычных платформах это исторически проблемная зона. - Нужно больше кода, чем в no-code или auto-extraction решениях; пауков ты пишешь и поддерживаешь сам.
- Мои тесты охватывали небольшие fixtures и демо-сайты, а не крупный краулинг — на масштабе надёжность в этом прогоне не подтверждена.
Для кого Scrapy, а кому лучше пройти мимо

Scrapy создан для разработчиков, которым нужен контроль на уровне кода и которые мыслят не страницами, а запросами. Если при виде медленного JavaScript-сайта у тебя первая мысль: «Тут где-то должен быть API», — этот инструмент сделан ровно под такой склад мышления. Он особенно хорош для тех, кто не боится писать селекторы, смотреть Network и брать на себя всю логику извлечения от начала до конца. Для статических сайтов, каталогов с пагинацией и всего, что питается от обнаруживаемого JSON-эндпоинта, он быстрый и точный.
Проходи мимо — или как минимум сочетай его с чем-то ещё — если писать и поддерживать код пауков не входит в то, как ты хочешь тратить время, либо если целевые сайты рендерят данные только на клиенте и воспроизводимого запроса там нет, а подключать headless-браузер ты не хочешь. И если ты надеялся просто дать инструменту URL и получить чистый структурированный вывод без написания правил извлечения, Scrapy никогда не был для этого предназначен и не делал вид, что был.
Альтернативы и место Thunderbit
Попробовать Thunderbit для извлечения веб-данных
Начинать стоит с понимания того, что именно ты покупаешь: бесплатный open-source фреймворк, который ты сам разворачиваешь и поддерживаешь. Ты владеешь пауками, стеком зависимостей и всей работой по поиску запросов к данным на каждом сайте. Взамен ты не платишь за каждый запрос, держишь всё внутри и получаешь полный контроль. Для многих команд это правильный выбор, и этот обзор не пытается переубедить их в обратном.
Компромисс упирается в проблему рендера и изменений на сайтах, и ответ Scrapy здесь такой: это твоя задача — найти API, повторить запрос и отдельно решить случай без API, подключив браузер. Управляемый AI-API для скрейпинга снимает этот слой с твоих плеч. Именно в эту нишу для технической аудитории попадает Thunderbit — AI API для извлечения данных плюс MCP-сервер плюс CLI, а не браузерное расширение, которым пользуются продажи и операционные команды. POST /distill превращает страницу в чистый Markdown, готовый для LLM; POST /extract возвращает структурированный JSON по схеме, которую ты задаёшь; и оба варианта обрабатывают JavaScript, антибот-защиту и динамический контент на стороне сервера — включая клиент-рендеренный случай, где Scrapy предлагает обратиться к браузеру. Есть MCP-сервер для AI-агентов и coding assistants (с бесплатным thunderbit_suggest_fields, чтобы заранее понять структуру страницы, прежде чем что-то тратить), а также CLI через npx @thunderbit/thunderbit-cli для терминала, CI или cron-задач.
Разница не в качестве, а в распределении ответственности. Scrapy — это инженерный фреймворк с явным контролем: ты ведёшь паука, pipeline и стратегию для JS, и получаешь полный контроль без платы за каждый вызов. В стеке Thunderbit слой рендера и извлечения отдаётся как управляемый сервис, поэтому ты пропускаешь поиск запросов в Network и платишь за вызов вместо того, чтобы поддерживать всё вручную. Небольшой проект, code-first подход и желание контролировать каждый шаг? Тогда Scrapy подходит лучше. Нужно масштабироваться на сотни сайтов и не хочется вручную воспроизводить запрос для каждого из них? Управляемый путь убирает эту категорию работы полностью.
Для более широкой картины эти обзоры показывают соседние решения: полное сравнение open-source скраперов, обзор Go-краулера Colly без браузера и обзор Scrapling с адаптивными селекторами.
Итог
Стоит ли использовать Scrapy? Да — если ты разработчик, которому нужен контроль, и тебе близка сама философия: не рендерить страницу, а находить запрос, который стоит за ней. В тестах эта идея сработала ровно так, как обещано. JavaScript-каталог дал HTTP-загрузчику 0 карточек, а JSON API, который его питал, отдал все 8 элементов тому же пауку. На статике извлечение дало 12/12, селекторы статьи сохранили 3/3 абзаца без мусора, граф обхода соблюдал ограничение глубины на 11 страницах, а статус 500 вернулся как обработанное состояние, а не падение.
Но формулировать вывод нужно точно. Scrapy не рендерит JavaScript и не ищет API за тебя — эту привычку нужно выработать самому. Стек зависимостей у него вполне фреймворковый и на необычных платформах способен доставить хлопоты, даже если у меня всё прошло чисто. И я тестировал fixtures и демо-страницы, а не краулинг на тысячу страниц, так что к истории про масштаб стоит относиться как к обнадёживающей, но пока не доказанной. В этих рамках Scrapy — это инструмент, который очень последовательно развивает почти радикальную идею: самый быстрый путь через веб-страницу чаще всего лежит вовсе не через саму страницу.
Попробовать Thunderbit для извлечения веб-данных Get Started Free
FAQ
Можно ли Scrapy скрапить страницы с JavaScript-рендерингом?
Не через стандартный HTTP-загрузчик — в моих тестах он вернул 0 узлов и на JS-фикстуре, и на публичной странице Quotes JS, потому что скачивает HTML без запуска браузера. Правильный путь — найти исходный запрос к данным, который делает страница, и обращаться напрямую к нему; в моём тесте JSON API за JS-каталогом отдал все 8 элементов. Если у страницы нет воспроизводимого запроса, браузер придётся подключать самостоятельно.
Что значит «повторить запрос»?
Большинство динамических страниц загружают данные из JSON API в фоне, а потом рисуют их на клиенте. Вместо того чтобы запускать браузер и смотреть, как это происходит, ты открываешь Network, находишь вызов API и направляешь Scrapy прямо на него. Это быстрее и стабильнее, чем рендерить страницу: контракт API ломается реже, чем DOM. Но работу всё равно нужно делать вручную, и Scrapy сам эндпоинт не найдёт.
Сложно ли установить Scrapy?
У меня всё прошло без проблем: pip install Scrapy==2.17.0 завершился без ошибок компиляции в свежем venv на macOS, используя бинарные колёса. Но пакет тянет за собой довольно большой стек (Twisted, lxml, cryptography, pyOpenSSL, parsel, tldextract), а официальная документация всё ещё предупреждает о платформенных нюансах на некоторых системах, так что если у тебя необычная среда, это нужно учитывать.
Какие форматы вывода поддерживает Scrapy?
Feed export из коробки поддерживает JSON, JSON Lines, CSV и XML — просто направляешь паука в файл, и он сериализует элементы без дополнительного кода. В моём прогоне один паук за один проход вывел и JSON, и CSV. Но важно помнить: он экспортирует выбранные тобой поля, а не автоматически превращает страницу в Markdown.
Можно ли использовать Scrapy в коммерческих проектах бесплатно?
Да, лицензия BSD-3-Clause очень свободная и подходит для коммерческого использования. Как всегда, перед внедрением лучше ещё раз проверить актуальную лицензию в репозитории, а также ответственно относиться к выбору user-agent, прокси и rate limit — возможность что-то делать ещё не означает, что это можно делать без ограничений.


