Scrapy – мощный Python-фреймворк для веб-скрейпинга. Для задач, требующих высокой производительности и масштабируемости, интеграция Scrapy с Redis может стать отличным решением. Redis, как in-memory хранилище данных, позволяет эффективно управлять очередью запросов, хранить результаты парсинга и реализовывать распределенный парсинг. В этой статье мы рассмотрим, как настроить и использовать Scrapy с Redis на практических примерах.
Зачем использовать Redis со Scrapy?
Scrapy сам по себе предоставляет хорошие возможности для парсинга, но Redis добавляет несколько важных преимуществ, особенно когда речь идет о больших объемах данных и параллельной обработке.
Преимущества использования Redis для масштабирования парсинга
-
Распределенная обработка: Redis позволяет распределить задачи парсинга между несколькими Scrapy-пауками, работающими на разных машинах.
-
Очередь запросов: Redis можно использовать как надежную очередь запросов, обеспечивая устойчивость к сбоям и гарантированную доставку.
-
Хранение состояния: Redis позволяет хранить состояние паука, например, список уже посещенных URL-ов, что предотвращает повторный парсинг.
Управление очередью запросов и распределенная обработка с Redis
Redis отлично подходит для управления очередью запросов благодаря своим атомарным операциям и высокой скорости работы. Scrapy-Redis использует списки Redis для хранения URL-ов, которые необходимо обработать. Несколько пауков могут одновременно читать и записывать в эту очередь, что позволяет масштабировать процесс парсинга.
Настройка Redis и Scrapy для совместной работы
Для начала необходимо установить и настроить Redis, а затем установить библиотеку scrapy-redis, которая обеспечивает интеграцию между Scrapy и Redis.
Установка и конфигурация Redis
Установка Redis зависит от вашей операционной системы. Например, на Ubuntu можно установить Redis следующим образом:
sudo apt update
sudo apt install redis-server
После установки Redis необходимо настроить. Основные параметры конфигурации находятся в файле /etc/redis/redis.conf. Для начала работы достаточно оставить настройки по умолчанию. Важно убедиться, что Redis доступен для подключения с вашей машины или сети.
Установка и настройка библиотеки Scrapy-Redis
Установите библиотеку scrapy-redis с помощью pip:
pip install scrapy-redis
Затем необходимо настроить Scrapy для использования Redis. В файле settings.py вашего проекта Scrapy добавьте следующие настройки:
# settings.py
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
# Enable Redis scheduler
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# Ensure all spiders share same duplicates filter through redis.
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# Store scraped item in redis for post processing.
ITEM_PIPELINES = {
'your_project.pipelines.RedisPipeline': 300,
}
# Redis Pipeline
REDIS_PIPELINE_KEY = '%(spider)s:items'
# Enable stats collection.
STATS_CLASS = 'scrapy_redis.stats.RedisStatsCollector'
# Start scrapy-redis requests flushing after max idle time (in seconds)
SCHEDULER_IDLE_BEFORE_CLOSE = 10
Пример 1: Простейший Scrapy паук с Redis
Рассмотрим пример простого Scrapy-паука, который использует Redis для хранения URL-ов для обхода.
Реализация паука, использующего Redis для хранения URL-ов
Создайте файл паука my_spider.py:
# my_spider.py
import scrapy
from scrapy_redis.spiders import RedisSpider
class MySpider(RedisSpider):
name = 'myspider'
redis_key = 'myspider:start_urls'
def parse(self, response):
# Извлечение данных со страницы
title = response.css('title::text').get()
yield {
'title': title,
'url': response.url
}
Этот паук наследуется от RedisSpider и использует ключ myspider:start_urls в Redis для получения начальных URL-ов. parse метод извлекает заголовок страницы и возвращает его в виде элемента.
Запуск и мониторинг паука
Запустите Redis-сервер. Заполните список URL-ов в Redis:
redis-cli lpush myspider:start_urls 'https://www.example.com'
redis-cli lpush myspider:start_urls 'https://www.scrapy.org'
Запустите паука Scrapy:
scrapy crawl myspider
Вы увидите, что паук обрабатывает URL-ы из Redis и выводит извлеченные данные.
Пример 2: Расширенное использование Scrapy-Redis
Рассмотрим более сложный пример, где Redis используется для фильтрации дубликатов и хранения данных.
Реализация dupefilter и scheduler с использованием Redis
В файле settings.py должны быть указаны параметры:
# settings.py
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
Теперь Scrapy будет использовать Redis для фильтрации дубликатов запросов, что предотвращает повторный парсинг одних и тех же страниц.
Настройка item pipeline для хранения данных в Redis
Создайте pipelines.py:
# pipelines.py
import redis
from scrapy.exceptions import DropItem
class RedisPipeline:
def __init__(self, redis_host, redis_port, redis_key):
self.redis_host = redis_host
self.redis_port = redis_port
self.redis_key = redis_key
self.r = None
@classmethod
def from_crawler(cls, crawler):
return cls(
redis_host=crawler.settings.get('REDIS_HOST'),
redis_port=crawler.settings.get('REDIS_PORT'),
redis_key=crawler.settings.get('REDIS_PIPELINE_KEY', '%(spider)s:items') % {
'spider': crawler.spider.name
}
)
def open_spider(self, spider):
self.r = redis.Redis(host=self.redis_host, port=self.redis_port)
def close_spider(self, spider):
self.r.close()
def process_item(self, item, spider):
key = self.redis_key % {'spider': spider.name}
self.r.lpush(key, str(item))
return item
В settings.py необходимо добавить данный pipeline.
ITEM_PIPELINES = {
'your_project.pipelines.RedisPipeline': 300,
}
Теперь все извлеченные данные будут сохраняться в Redis в виде списка.
Альтернативы Scrapy-Redis и оптимизация
Хотя Scrapy-Redis – популярное решение, существуют и другие подходы к масштабированию Scrapy.
Сравнение Scrapy-Redis с другими решениями для масштабирования Scrapy
-
Scrapy + Celery: Celery – это распределенная система очередей задач. Она может использоваться вместо Redis для управления очередью запросов.
-
Scrapy + Kafka: Kafka – это платформа потоковой передачи данных. Она может использоваться для хранения и обработки больших объемов данных, извлеченных Scrapy.
Выбор решения зависит от конкретных требований проекта.
Оптимизация производительности Scrapy и Redis при совместном использовании
-
Используйте пулы соединений Redis: Это уменьшает накладные расходы на установление новых соединений.
-
Настройте параметры Redis: Оптимизируйте
redis.confдля вашей рабочей нагрузки. Увеличьтеmaxmemory, если это необходимо. -
Используйте конвейеры Redis: Это позволяет отправлять несколько команд Redis за один раз, что увеличивает производительность.
-
Уменьшите размер элементов Scrapy: Меньшие элементы означают меньшую нагрузку на сеть и Redis.
Заключение
Интеграция Scrapy с Redis – эффективный способ масштабирования парсинга данных. В этой статье мы рассмотрели основные шаги по настройке и использованию Scrapy-Redis, а также альтернативные решения и методы оптимизации производительности. Надеемся, что эти примеры помогут вам в ваших проектах веб-скрейпинга.