Scrapy – веб-скрейпинг

онлайн тренер по питону
Онлайн-тренажер Python 3 для начинающих

Теория без воды. Задачи с автоматической проверкой. Подсказки на русском языке. Работает в любом современном браузере.

начать бесплатно

Введение в Scrapy

Scrapy — это асинхронный фреймворк на Python для веб-скрейпинга, предназначенный для масштабируемого сбора данных с сайтов. Он позволяет автоматически переходить по ссылкам, извлекать структурированные данные, обрабатывать формы, взаимодействовать с API и сохранять результаты в различных форматах. Scrapy активно используется в проектах анализа данных, мониторинга цен, парсинга новостей, научных исследований и автоматизации сбора информации.


Основные возможности и преимущества

  • Асинхронная архитектура на базе Twisted

  • Поддержка CSS и XPath селекторов

  • Высокая производительность и масштабируемость

  • Гибкая настройка middleware, headers, proxy

  • Интеграция с API, JSON, XML

  • Сохранение в JSON, CSV, базу данных

  • Расширение через плагины и модули


Установка и создание проекта Scrapy

Установка Scrapy:

bash
pip install scrapy

Создание проекта:

bash
scrapy startproject myproject cd myproject

Структура проекта Scrapy

markdown
myproject/ ├── myproject/ │ ├── __init__.py │ ├── items.py │ ├── middlewares.py │ ├── pipelines.py │ ├── settings.py ├── spiders/ │ └── example_spider.py └── scrapy.cfg
  • spiders/ — пауки

  • items.py — структуры для данных

  • pipelines.py — обработка результатов

  • settings.py — настройки проекта


Создание паука (Spider)

python
import scrapy class QuotesSpider(scrapy.Spider): name = "quotes" start_urls = ['https://quotes.toscrape.com'] def parse(self, response): for quote in response.css('div.quote'): yield { 'text': quote.css('span.text::text').get(), 'author': quote.css('small.author::text').get(), }

Запуск:

bash
scrapy crawl quotes

Навигация и переход по ссылкам

python
def parse(self, response): for link in response.css('li.next a::attr(href)').getall(): yield response.follow(link, self.parse)

response.follow() автоматически добавляет базовый URL.


Извлечение данных с помощью XPath и CSS

CSS селекторы:

python
response.css('div.title::text').get()

XPath селекторы:

python
response.xpath('//div[@class="title"]/text()').get()

Получение всех значений:

python
response.css('ul li::text').getall()

Обработка и сохранение результатов

Сохранение в файл:

bash
scrapy crawl quotes -o quotes.json scrapy crawl quotes -o data.csv

Поддержка форматов: JSON, CSV, XML, JL (JSON Lines)


Использование Item и ItemLoader

python
# items.py import scrapy class QuoteItem(scrapy.Item): text = scrapy.Field() author = scrapy.Field()

В spider.py:

python
from myproject.items import QuoteItem item = QuoteItem() item['text'] = quote.css('span.text::text').get()

С ItemLoader:

python
from scrapy.loader import ItemLoader loader = ItemLoader(item=QuoteItem(), selector=quote) loader.add_css('text', 'span.text::text') yield loader.load_item()

Работа с Middleware и User-Agent

Настройка User-Agent:

python
# settings.py USER_AGENT = 'Mozilla/5.0 (compatible; ScrapyBot)'

Custom middleware:

python
# middlewares.py class CustomHeaderMiddleware: def process_request(self, request, spider): request.headers['X-Custom-Header'] = 'value'

Параллельность и ограничения скорости

Ограничение скорости:

python
DOWNLOAD_DELAY = 1 # секунд CONCURRENT_REQUESTS = 8

Поддержка AutoThrottle:

python
AUTOTHROTTLE_ENABLED = True

Аутентификация и обработка форм

python
yield scrapy.FormRequest( url='https://example.com/login', formdata={'username': 'user', 'password': 'pass'}, callback=self.after_login )

Работа с API и JSON

Извлечение JSON:

python
import json def parse(self, response): data = json.loads(response.text) yield data

Запрос к API:

python
yield scrapy.Request(url='https://api.example.com/data', callback=self.parse_json)

Запуск, логирование и отладка

Запуск с логом:

bash
scrapy crawl quotes --nolog

Просмотр ответа:

bash
scrapy shell 'https://example.com' response.css('h1::text').get()

Развёртывание Scrapy на сервере

Варианты:

  • Scrapy Cloud — облачное развёртывание от Scrapinghub

  • Docker — контейнеризация Scrapy

  • cron + логика запуска скриптов — автоматизация


Расширение Scrapy: Splash, Selenium, ScrapyRT

  • Scrapy-Splash — парсинг JavaScript-страниц

  • Scrapy-Selenium — интеграция с Selenium WebDriver

  • ScrapyRT — запуск пауков через HTTP API


Примеры практического применения

  • Сбор цен и характеристик товаров

  • Мониторинг новостей и обновлений

  • Извлечение данных для машинного обучения

  • Сбор данных из бирж и финансовых сервисов

  • Парсинг вакансий и предложений на сайтах


Часто задаваемые вопросы

Что такое Scrapy?

Фреймворк на Python для высокопроизводительного сбора данных с веб-сайтов (веб-скрейпинга).

Поддерживает ли Scrapy JavaScript?

Нет напрямую. Для JavaScript-контента используется Scrapy-Splash или Selenium.

Можно ли сохранять данные в базу данных?

Да, через pipelines или внешние библиотеки (например, SQLAlchemy, MongoDB).

Как ограничить скорость запросов?

Через DOWNLOAD_DELAY, CONCURRENT_REQUESTS и AUTOTHROTTLE.

Подходит ли Scrapy для API?

Да, поддерживает JSON, REST, XML.

Полный справочник по ключевым функциям и структуре библиотеки Scrapy для Python

Установка

bash
pip install scrapy

Создание нового проекта:

bash
scrapy startproject myproject cd myproject

Создание нового паука (spider):

bash
scrapy genspider myspider example.com

Структура Scrapy-проекта

Файл / Папка Назначение
spiders/ Папки с пауками (основная логика парсинга).
items.py Определение структуры данных (аналог схемы).
pipelines.py Постобработка и сохранение данных.
middlewares.py Обработка запросов/ответов (например, User-Agent).
settings.py Настройки проекта (timeouts, user-agent, экспорт и др.).
scrapy.cfg Конфигурация проекта.

Основы: создание паука

python
import scrapy class MySpider(scrapy.Spider): name = "example" start_urls = ['https://example.com'] def parse(self, response): title = response.css('title::text').get() yield {'title': title}

Основные методы response

Метод Описание
response.css(selector) Поиск через CSS-селекторы.
response.xpath(xpath) Поиск через XPath.
.get() Возвращает первое значение.
.getall() Возвращает список всех найденных значений.
.attrib Доступ к атрибутам HTML-тега.
response.url, response.status, response.body URL, статус, содержимое.

Извлечение данных

python
# CSS title = response.css('h1::text').get() # XPath description = response.xpath('//p[@class="desc"]/text()').get()

Следование по ссылкам

python
def parse(self, response): for href in response.css("a::attr(href)").getall(): yield response.follow(href, callback=self.parse_detail) def parse_detail(self, response): yield { 'url': response.url, 'title': response.css('title::text').get() }

Items (структура данных)

python
# items.py import scrapy class ProductItem(scrapy.Item): name = scrapy.Field() price = scrapy.Field()

Использование:

python
item = ProductItem() item['name'] = "Товар" item['price'] = "100 руб" yield item

Pipelines (сохранение и обработка)

python
# pipelines.py class SaveToTxtPipeline: def process_item(self, item, spider): with open("data.txt", "a") as f: f.write(f"{item['name']} - {item['price']}\n") return item

Активация в settings.py:

python
ITEM_PIPELINES = { 'myproject.pipelines.SaveToTxtPipeline': 300, }

Запуск паука

bash
scrapy crawl example

Экспорт результата:

bash
scrapy crawl example -o result.json scrapy crawl example -o result.csv

Обход robots.txt

Отключение:

python
ROBOTSTXT_OBEY = False # в settings.py

Пользовательский User-Agent и заголовки

python
DEFAULT_REQUEST_HEADERS = { 'User-Agent': 'MyScraperBot/1.0', }

Обход блокировок