Гид по технологиям

Как создать веб-краулер на Python с помощью Scrapy

5 min read Разработка Обновлено 05 Apr 2026
Веб-краулер на Python с Scrapy
Веб-краулер на Python с Scrapy

Скриншот страницы с примером парсинга

Что вы узнаете

  • Кратко о Scrapy и зачем он нужен
  • Как установить и запустить простого паука
  • Как извлекать текст, атрибуты и сохранять в JSON/CSV
  • Когда Scrapy не подходит и какие есть альтернативы
  • Практический чеклист, методология и меры безопасности

Что такое Scrapy

Scrapy — это фреймворк на Python для парсинга и создания пауков (spiders). Определение в одну строку: Scrapy предоставляет удобные инструменты для обхода страниц, выбора элементов и экспорта данных.

Важно: Scrapy работает на стороне сервера и по умолчанию не выполняет JavaScript. Для сайтов с динамической отрисовкой нужна альтернатива.

Установка Scrapy

Рекомендуется использовать виртуальное окружение, чтобы не менять системные пакеты. Ниже — команды для Unix-подобных систем (Linux, macOS) из исходного материала.

mkdir crawler  
cd crawler  
virtualenv venv  
. venv/bin/activate  

Если вы на Windows с стандартным venv:

python -m venv venv
venv\Scripts\activate

Установите Scrapy:

pip install scrapy

Проверьте установку:

scrapy
# prints
Scrapy 1.4.0 - no active project

Usage:
  scrapy  [options] [args]

Available commands:
  bench         Run quick benchmark test
  fetch         Fetch a URL using the Scrapy downloader
  genspider     Generate new spider using pre-defined templates
  runspider     Run a self-contained spider (without creating a project)
...

Совет: используйте pip-tools или Poetry для фиксации зависимостей в проекте.

Создание простого паука

Пример берёт страницу Википедии о батареях. Основные элементы паука:

  • name — идентификатор паука
  • start_urls — список начальных URL
  • parse(self, response) — метод обработки ответа

Исходный код:

import scrapy  
  
class spider1(scrapy.Spider):  
    name = 'Wikipedia'  
    start_urls = ['https://en.wikipedia.org/wiki/Battery_(electricity)']  
  
    def parse(self, response):  
        pass  

Запустите для теста:

scrapy runspider spider1.py  
# prints
2017-11-23 09:09:21 [scrapy.utils.log] INFO: Scrapy 1.4.0 started (bot: scrapybot)
2017-11-23 09:09:21 [scrapy.utils.log] INFO: Overridden settings: {'SPIDER_LOADER_WARN_ONLY': True}
2017-11-23 09:09:21 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.memusage.MemoryUsage',
 'scrapy.extensions.logstats.LogStats',
...  

Отключение лишних логов

Чтобы лог не забивал консоль, настраиваем уровень логирования:

import logging  
logging.getLogger('scrapy').setLevel(logging.WARNING)  

Это полезно при отладке вывода, когда нужны только явные ошибки и предупреждения.

Как работать с DOM и Chrome Inspector

Вся страница — набор HTML-элементов в структуре DOM. Инструменты разработчика в Chrome помогают быстро находить селекторы:

  • Откройте страницу в Chrome
  • Наведите мышь на элемент
  • Правый клик → Inspect

Панель Elements покажет дерево элементов и поможет сформировать CSS- или XPath-селектор.

Примечание: иногда полезнее строить XPath, если структура сложная или классы динамические.

Извлечение заголовка страницы

Чтобы получить текст заголовка (h1#firstHeading) используйте CSS-селектор с ::text:

...  
    def parse(self, response):  
        print response.css('h1#firstHeading::text').extract()  
...  

response.css() возвращает селекторы; добавление ::text и .extract() даёт текстовый контент.

Пример вывода:

    [u'Battery (electricity)']

Извлечение первого абзаца с описанием

В Chrome вы видите путь:

    div#mw-content-text>div>p

Чтобы взять первый элемент p:

response.css('div#mw-content-text>div>p')[0]  

Добавляем ::text и собираем строки в одну:

response.css('div#mw-content-text>div>p')[0].css('::text')  

Итоговая версия:

    def parse(self, response):  
        print ''.join(response.css('div#mw-content-text>div>p')[0].css('::text').extract())  

Это вернёт первый абзац текста страницы.

Сбор структурированных данных в JSON

Scrapy удобно отдаёт элементы через yield — слова-ключи превращаются в записи JSON/CSV при запуске.

Пример: собрать все абзацы в JSON:

...  
    def parse(self, response):  
        for e in response.css('div#mw-content-text>div>p'):  
            yield { 'para' : ''.join(e.css('::text').extract()).strip() }  
...  

Запуск с записью в файл:

scrapy runspider spider3.py -o joe.json  

Пример вывода (сокращённо):

[  
{"para": "An electric battery is a device consisting of ..."},  
{"para": "Primary (single-use or \"disposable\") batteries are used once ..."},  
...  
]

Совет: для больших объёмов данных используйте конвейер (Item Pipeline) и подключайте базу данных или облачное хранилище.

Парсинг нескольких элементов в одной записи

Пример с IMDb (boxoffice): извлекаем название, уикенд, суммарно и изображение.

...  
    def parse(self, response):  
        for e in response.css('div#boxoffice>table>tbody>tr'):  
            yield {  
                'title': ''.join(e.css('td.titleColumn>a::text').extract()).strip(),  
                'weekend': ''.join(e.css('td.ratingColumn')[0].css('::text').extract()).strip(),  
                'gross': ''.join(e.css('td.ratingColumn')[1].css('span.secondaryInfo::text').extract()).strip(),  
                'weeks': ''.join(e.css('td.weeksColumn::text').extract()).strip(),  
                'image': e.css('td.posterColumn img::attr(src)').extract_first(),  
            }  
...  

Результат можно экспортировать в JSON или CSV при запуске.

Когда Scrapy не подходит

  • Сайты с тяжелым JavaScript, которые динамически рендерят контент. Тогда используйте Selenium, Playwright или headless браузер.
  • CAPTCHA, строгие защиты и анти-бот механизмы — потребуются прокси, анти-капча или ручная интеграция, но учтите юридические риски.
  • Интерактивные действия (файлы, сложные формы, WebSocket) — иногда проще автоматизировать браузер.

Альтернативные инструменты:

  • Selenium / Playwright — имитация реального браузера, выполняют JS
  • Requests + BeautifulSoup — лёгкие сценарии без обхода ссылок
  • Puppeteer (Node.js) — управление Chrome/Chromium

Практическая методология для одного задания (mini-methodology)

  1. Определите цель парсинга: какие поля и в каком формате нужны.
  2. Откройте страницу в браузере и найдите элементы через Inspector.
  3. Подберите CSS или XPath селекторы и протестируйте их в консоли.
  4. Напишите паука с аккуратной обработкой ошибок и таймаутами.
  5. Уважайте robots.txt и Terms of Service сайта.
  6. Логируйте скорости и ошибки; добавьте повторные попытки и лимиты.
  7. Экспортируйте в требуемый формат и валидируйте данные.

Чеклист разработчика

  • Виртуальное окружение настроено
  • Scrapy установлен и запускается
  • Селекторы протестированы в Inspector
  • Лимит запросов (CONCURRENT_REQUESTS) настроен
  • DOWNLOAD_DELAY установлен для вежливости
  • User-Agent настроен корректно
  • Обработка ошибок/повторных попыток реализована
  • Данные сохраняются в нужном формате
  • Логи записываются и мониторятся

Рекомендация: задайте DOWNLOAD_DELAY в настройках проекта и используйте AutoThrottle для адаптивной нагрузки.

Шпаргалка по CSS и XPath (cheat sheet)

  • CSS по классу: .className
  • CSS по id: #elementId
  • Дочерний элемент: parent > child
  • Любой потомок: ancestor descendant
  • Атрибут: a::attr(href) или img::attr(src)
  • Текст: ::text
  • Первый элемент списка: selector[0]

XPath примеры:

  • //div[@id=’mw-content-text’]//p[1] — первый p под div с id
  • //table//tr — все строки таблицы

Риски и смягчение

  • Юридические вопросы: проверьте Terms of Service и robots.txt. Если есть сомнения — запросите разрешение.
  • Блокировка IP: используйте ротацию прокси, но не для обхода законных запретов.
  • Перегрузка сервера: ставьте задержки и используйте AutoThrottle.
  • Потеря данных: валидируйте экспорт и храните контрольные суммы.

Критерии приёмки

  • Паук собирает 95% целевых полей без ошибок при трёх прогонах
  • Лимит запросов не превышает политики сайта
  • Экспорт в требуемом формате (JSON/CSV) корректен и валиден
  • Логи ошибок содержат удобные трассировки для отладки

Пример работы с пагинацией

Типично пагинация реализуется через ссылки “Next”. В parse() найдите ссылку и вызовите response.follow:

for item in response.css('div.listing'):  
    yield parse_item(item)  
next_page = response.css('a.next::attr(href)').get()  
if next_page:
    yield response.follow(next_page, self.parse)

Решение задач с авторизацией

Если нужен вход в аккаунт:

  • Используйте FormRequest для отправки форм логина
  • Храните куки через сессии Scrapy
  • Для JavaScript-логина — используйте headless браузер

Визуальная логика принятия решения

Ниже — простое дерево выбора между Scrapy и браузерной автоматизацией (Mermaid):

flowchart TD
    A[Нужен парсинг] --> B{Контент рендерится JS?}
    B -- Нет --> C[Используйте Scrapy]
    B -- Да --> D{Можно ли получить API?}
    D -- Да --> E[Запросы к API]
    D -- Нет --> F[Используйте Playwright/Selenium]

(Скопируйте блок Mermaid в инструмент, который поддерживает рендеринг.)

Короткое резюме

Scrapy — мощный инструмент для структурированного парсинга: он лёгкий для старта и расширяемый для промышленных задач. Для динамических или защищённых сайтов рассматривайте браузерные решения.

Важно: уважайте правила сайтов и законы о защите данных при сборе и хранении информации.

Короткий список дальнейших шагов:

  • Попрактикуйтесь на простых страницах (википедия, блоги)
  • Освойте Item Pipelines для сохранения данных
  • Изучите middleware и настройки скорости
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Починить ассоциации .lnk в Windows 7
Windows

Починить ассоциации .lnk в Windows 7

Исправить проблемы Instagram: обходы и инструменты
Социальные сети

Исправить проблемы Instagram: обходы и инструменты

Как заменить аккумулятор ноутбука
Аппаратное обеспечение

Как заменить аккумулятор ноутбука

Звук зарядки MacBook: включить, отключить, изменить
MacBook

Звук зарядки MacBook: включить, отключить, изменить

Невидимые символы в документах: как смотреть и исправлять
Документы

Невидимые символы в документах: как смотреть и исправлять

Уведомления о звонках Android на ПК
Руководства

Уведомления о звонках Android на ПК