Обзор Scrapy 2.17: без браузера, зато сразу к API

Последнее обновление: July 17, 2026
Обзор Scrapy 2.17: без браузера, зато сразу к API
AI-сводка
Этот обзор Scrapy оспаривает распространённое мнение, что фреймворк устарел из-за отсутствия поддержки JavaScript. Тесты показывают, что Scrapy особенно силён тогда, когда может воспроизвести исходный HTTP- или JSON API-запрос, стоящий за страницей, и получить чистый структурированный результат без накладных расходов браузера. В статье рассматриваются извлечение со статических страниц, динамические данные через API, обработка ошибок, feed export, стоимость установки и граница, за которой уже нужен браузерный рендеринг. Scrapy показан как зрелый, «производственный» краулер для HTTP-first скрейпинга, очередей, pipeline и экспорта — а не как универсальное решение для любой страницы с JavaScript-рендерингом.

Scrapy часто относят к инструментам, которые «не тянут современные сайты», потому что он не запускает JavaScript. Но это как раз перевёрнутое понимание. Смысл Scrapy как раз в том, чтобы не рендерить страницу, и как только видишь это в работе, отсутствие браузера уже не кажется минусом.

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

Что такое Scrapy на самом деле — и чем он не является

Scrapy HTTP-only workflow

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 подхода, именно так.

Установка: стек зависимостей, который обычно никто не показывает

Scrapy dependency stack

Установка прошла без происшествий, и для такого крупного фреймворка это само по себе стоит отметить. Команда 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, так что если у тебя нестандартная система, это стоит закладывать заранее. В моём случае всё прошло гладко, но размер устанавливаемого стека всё равно полезно понимать до старта: ты ставишь фреймворк, а фреймворк и весит как фреймворк.

Практика: что сработало без нареканий

Scrapy hands-on results

После установки всё, что касалось статических страниц, отработало ровно. Полное извлечение без потерь.

ТестРезультатВремя
Локальный статический каталог + пагинация12/12 товаров0.557s
Экспорт CSV из статического каталогазаписано 12 строк(тот же прогон)
Извлечение статьизаголовок + 3/3 абзаца0.416s
Граф обхода, DEPTH_LIMIT=211 страниц на глубинах 0/1/20.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-стена и дверь рядом с ней

Scrapy JS page 0 nodes vs JSON API 8/8

Теперь — тот самый результат, вокруг которого и строится этот обзор.

Я направил 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 manual API boundary

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 — возможность что-то делать ещё не означает, что это можно делать без ограничений.

Ke
Ke
Технический директор в Thunderbit | Senior Data Scientist и эксперт по ML Имея почти десятилетний опыт в машинном обучении и data science, Кэ Шэнь — выпускник Колумбийского университета и бывший Senior Data Scientist в Walmart Labs. Обладая глубокой, признанной коллегами экспертизой в Python, R, Java и статистике, он делится проверенными на практике наблюдениями о том, как переводить сложные AI-алгоритмы из теории в production-grade архитектуру.
Topics
Web Scraping ToolsAI Web Scraper

Попробуй Thunderbit

Собирай лиды и другие данные всего в 2 клика. На базе AI.

Получить Thunderbit Это бесплатно
Извлекай данные с помощью AI
Легко передавай данные в Google Sheets, Airtable или Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week