Scrapy: фреймворк для масштабного краулинга

Scrapy — это не библиотека, а целый фреймворк для промышленного краулинга.
Scrapy берёт на себя всё: очередь запросов, асинхронную загрузку, повторы при сбоях, экспорт данных. Ты пишешь только «пауков» — классы, которые говорят, что скачать и как разобрать.

Когда задача вырастает из «спарсить одну страницу» в «обойти весь сайт на тысячи страниц с повторами, ограничением скорости и сохранением в базу», ручной код на requests становится громоздким. Scrapy решает это архитектурно: он асинхронный (работает на Twisted), сам управляет очередью и параллелизмом, и из коробки умеет экспортировать в JSON/CSV. Установка:

pip install scrapy

Минимальный паук (запускать у себя):

import scrapy

class QuotesSpider(scrapy.Spider):
    name = 'quotes'
    start_urls = ['https://quotes.toscrape.com/']

    # вежливость: задержка между запросами
    custom_settings = {'DOWNLOAD_DELAY': 1.0}

    def parse(self, response):
        for quote in response.css('div.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 response.follow(next_page, callback=self.parse)

Запуск с экспортом одной командой:

scrapy crawl quotes -o quotes.json

Как работает под капотом

Паук возвращает (yield) два типа объектов: словари (это извлечённые данные) и Request (это «сходи ещё сюда»). Scrapy сам ставит запросы в очередь, скачивает их асинхронно и передаёт ответы обратно в parse. Метод response.follow удобно строит следующий запрос из относительной ссылки. Селекторы response.css/response.xpath встроены — отдельный BeautifulSoup не нужен.

Почему фреймворк, а не скрипт

На первый взгляд непонятно, зачем целый фреймворк, если обход страниц можно написать циклом на requests. Разница проявляется на масштабе. Свой скрипт нужно вручную снабдить: очередью ссылок без дублей, повторами при сбоях, ограничением скорости, параллелизмом, экспортом в разные форматы, логированием, обработкой кодировок. Scrapy даёт всё это из коробки и асинхронно — пока один запрос ждёт ответа, другие уже выполняются, что радикально ускоряет обход тысяч страниц без ручного управления потоками.

Структура проекта тоже не случайна. Scrapy разделяет ответственность: пауки отвечают за «что и как парсить», Item-классы описывают структуру данных, пайплайны — за их обработку и сохранение, настройки — за поведение краулера. Такое разделение делает большой проект поддерживаемым: добавить новый источник — значит написать ещё одного паука, не трогая логику сохранения. Для разовой задачи на одну страницу это избыточно, и тогда честнее взять requests. Но как только проект становится постоянным конвейером данных, продуманная архитектура Scrapy окупается.

Частые ошибки

  • Тянуть Scrapy для одной страницы. Для разовой задачи requests + bs4 проще. Scrapy раскрывается на больших обходах.
  • Не ставить DOWNLOAD_DELAY. По умолчанию Scrapy быстрый — без задержки легко перегрузить сайт.
  • Возвращать через return вместо yield. Паук — генератор; данные и запросы отдаются через yield.

Best practices

  • Всегда настраивай DOWNLOAD_DELAY и включай AUTOTHROTTLE для вежливости.
  • Используй response.follow для ссылок — он сам делает их абсолютными.
  • Экспортируй данными командой -o, а не пиши файлы руками.

Запуск паука удобно осваивать через интерактивную консоль scrapy shell URL: она загружает страницу и даёт готовый объект response, на котором можно прямо в терминале пробовать селекторы и сразу видеть результат. Это резко ускоряет разработку парсера — не нужно гонять весь паук ради проверки одного выражения, и не нужно лишний раз запрашивать сайт. Освоение scrapy shell — один из главных приёмов продуктивной работы с фреймворком.

Создать проект Scrapy помогают встроенные команды-генераторы: scrapy startproject myshop разворачивает каркас с настройками и папкой для пауков, а scrapy genspider quotes example.com добавляет заготовку паука. Такой типовой скелет — ещё одна причина выбирать фреймворк: структура проекта одинакова у всех, и любой знакомый со Scrapy разработчик сразу понимает, где что лежит. Единые соглашения экономят время команды и упрощают передачу проекта между людьми — важное свойство для систем, которые собирают данные не разово, а постоянно.

Итог: Scrapy — фреймворк для масштабного краулинга. Паук через yield отдаёт данные и новые запросы, а фреймворк берёт на себя очередь, асинхронность и экспорт.

Проверьте себя
1. Что паук Scrapy отдаёт через yield в методе parse?
AТолько текст страницы
BСловари с данными и/или объекты Request для перехода на другие страницы
CТолько HTML
DНичего
2. Зачем в пауке настраивать DOWNLOAD_DELAY?
AЧтобы замедлить интернет
BЧтобы добавить задержку между запросами и не перегружать сайт (вежливость)
CЭто ускоряет краулинг
DПараметр бесполезен