Примеры Scrapy Middleware: Руководство по Использованию и Настройке для Веб-Скрейпинга

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 данные проходят через несколько этапов:

  1. Spider: Определяет, какие URL адреса нужно скрапить и как обрабатывать полученные данные.

  2. Engine: Управляет потоком запросов и ответов.

  3. Downloader: Загружает контент с веб-сайтов.

  4. 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 позволяет создавать более надежные и эффективные проекты веб-скрейпинга.


Добавить комментарий