Scrapy – мощный фреймворк для веб-скрейпинга на Python. Middleware – это сердце Scrapy, позволяющее гибко управлять потоком запросов и ответов. В этой статье мы рассмотрим, что такое Scrapy middleware, как его использовать и настраивать, а также приведем практические примеры для решения распространенных задач веб-скрейпинга.
Что такое Scrapy Middleware и зачем он нужен?
Определение и роль Middleware в Scrapy
Middleware в Scrapy – это компоненты, которые обрабатывают запросы и ответы на различных этапах скрапинга. Они действуют как посредники, перехватывая и модифицируя данные между движком Scrapy, spiders (пауками) и downloader-ом (загрузчиком).
Преимущества использования Middleware для веб-скрейпинга
-
Гибкость: Middleware позволяет настраивать процесс скрапинга под конкретные нужды, не изменяя код spiders.
-
Повторное использование: Middleware можно использовать в нескольких проектах.
-
Модульность: Отдельные middleware выполняют определенные задачи, что облегчает отладку и поддержку.
-
Решение распространенных проблем: Middleware помогают обходить блокировки, управлять cookie, обрабатывать ошибки и многое другое.
Архитектура Scrapy и место Middleware в ней
Поток данных через Scrapy: Spider, Downloader, Engine
В Scrapy данные проходят через несколько этапов:
-
Spider: Определяет, какие URL адреса нужно скрапить и как обрабатывать полученные данные.
-
Engine: Управляет потоком запросов и ответов.
-
Downloader: Загружает контент с веб-сайтов.
-
Middleware: Перехватывают и обрабатывают запросы и ответы между этими компонентами.
Типы Middleware: Spider Middleware и Downloader Middleware
Существует два основных типа middleware:
-
Spider Middleware: Обрабатывает данные между Spider и Engine. Может модифицировать элементы (items), запросы (requests) и ответы (responses) перед отправкой их в движок или обратно в spider.
-
Downloader Middleware: Обрабатывает запросы и ответы между Engine и Downloader. Используется для добавления заголовков (headers), использования прокси, обработки ошибок и т.д.
Практические примеры Scrapy Downloader Middleware
Реализация User-Agent Middleware для обхода блокировок
Многие сайты блокируют запросы без User-Agent. Middleware позволяет добавить или изменить User-Agent в каждом запросе. Вот пример:
class RandomUserAgentMiddleware:
def __init__(self, user_agent_list):
self.user_agent_list = user_agent_list
@classmethod
def from_crawler(cls, crawler):
return cls(crawler.settings.get('USER_AGENT_LIST'))
def process_request(self, request, spider):
import random
ua = random.choice(self.user_agent_list)
request.headers['User-Agent'] = ua
В settings.py необходимо добавить список User-Agent:
USER_AGENT_LIST = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0'
]
DOWNLOADER_MIDDLEWARES = {
'your_project.middlewares.RandomUserAgentMiddleware': 400,
}
Использование Proxy Middleware для анонимного скрейпинга
Proxy middleware позволяет отправлять запросы через прокси-серверы, маскируя ваш IP-адрес. Пример:
import random
class ProxyMiddleware:
def __init__(self, proxy_list):
self.proxy_list = proxy_list
@classmethod
def from_crawler(cls, crawler):
return cls(crawler.settings.get('PROXY_LIST'))
def process_request(self, request, spider):
proxy = random.choice(self.proxy_list)
request.meta['proxy'] = proxy
В settings.py добавьте список прокси и активируйте middleware:
PROXY_LIST = [
'http://user:password@192.168.1.100:3128',
'http://10.10.10.10:8080',
]
DOWNLOADER_MIDDLEWARES = {
'your_project.middlewares.ProxyMiddleware': 750,
}
Создание и Настройка Scrapy Spider Middleware
Обработка и модификация данных, полученных от Spider
Spider middleware позволяет обрабатывать данные, полученные от spider, перед их передачей в pipeline. Это полезно для фильтрации, модификации или обогащения данных.
Пример middleware для фильтрации дубликатов
Этот middleware фильтрует дубликаты элементов, основываясь на определенном поле (например, URL):
class DuplicatesFilterMiddleware:
def __init__(self):
self.seen_urls = set()
def process_spider_output(self, response, result, spider):
for item in result:
if hasattr(item, 'get') and item.get('url') in self.seen_urls:
continue
self.seen_urls.add(item.get('url'))
yield item
В settings.py активируйте middleware:
SPIDER_MIDDLEWARES = {
'your_project.middlewares.DuplicatesFilterMiddleware': 100,
}
Расширенные возможности Middleware: Обработка ошибок и логирование
Обработка исключений и повторные попытки запросов (Retry Middleware)
Scrapy предоставляет встроенный Retry Middleware, который автоматически повторяет неудачные запросы. Для настройки повторных попыток, измените параметры RETRY_TIMES и RETRY_HTTP_CODES в settings.py.
RETRY_TIMES = 2 # Количество повторных попыток
RETRY_HTTP_CODES = [500, 502, 503, 504, 400, 408] # Коды HTTP, при которых следует повторять запрос
Также можно создать свой Retry Middleware для более сложной логики:
from scrapy.exceptions import IgnoreRequest
class CustomRetryMiddleware:
def process_spider_exception(self, response, exception, spider):
if isinstance(exception, IgnoreRequest):
# Логика повторной отправки запроса
new_request = response.request.copy()
new_request.dont_filter = True # Чтобы Scrapy не фильтровал повторные запросы
return new_request
Логирование запросов и ответов с помощью Middleware
Middleware можно использовать для логирования запросов и ответов, что полезно для отладки и мониторинга:
import logging
class LoggingMiddleware:
def process_request(self, request, spider):
logging.info(f'Отправлен запрос: {request.url}')
def process_response(self, request, response, spider):
logging.info(f'Получен ответ: {response.url}, status: {response.status}')
return response
def process_exception(self, request, exception, spider):
logging.error(f'Произошла ошибка при запросе: {request.url}, exception: {exception}')
Заключение
Scrapy Middleware – это мощный инструмент для настройки и расширения функциональности Scrapy. Примеры, представленные в этой статье, демонстрируют, как middleware можно использовать для решения различных задач, от обхода блокировок до обработки ошибок и логирования. Понимание и умелое использование middleware позволяет создавать более надежные и эффективные проекты веб-скрейпинга.