Skip to content
Advanced / 3 min read

Продвинутая ротация ProxyScrape в Scrapy: пользовательское промежуточное ПО загрузчика с повторными попытками и обнаружением блокировок

Создайте пользовательское промежуточное ПО загрузчика Scrapy, которое выполняет ротацию резидентных и датацентровых прокси ProxyScrape, обрабатывает повторные попытки и обнаруживает блокировки для надежного крупномасштабного скрейпинга.

Linux SOCKS5 HTTP(S) Веб-скрейпинг

Обзор

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

ProxyScrape предоставляет резидентные, датацентровые и мобильные прокси с поддержкой HTTP и SOCKS5, пул из более чем 97 млн IP-адресов и высокий уровень долгосрочной работы. Вы можете выбрать оплату по факту использования или фиксированную ежемесячную оплату в зависимости от объема скрейпинга.

Предварительные требования

  • Установлен Python 3.8 или новее.
  • Установлен Scrapy (pip install scrapy).
  • Аккаунт ProxyScrape с включенными резидентными или датацентровыми прокси.
  • Ваш эндпоинт прокси и учетные данные из панели управления ProxyScrape.
  • Необязательно: список отдельных эндпоинтов прокси, если вы предпочитаете статическую ротацию вместо ротационного эндпоинта.

Шаг 1: Создайте проект Scrapy

Откройте терминал и создайте новый проект Scrapy:

pip install scrapy
scrapy startproject proxyscrape_scraper
cd proxyscrape_scraper

Шаг 2: Безопасно сохраните учетные данные ProxyScrape

Никогда не вставляйте учетные данные напрямую в исходные файлы. Используйте переменные среды и считывайте их в settings.py.

Создайте файл .env или экспортируйте переменные в оболочке:

export PROXYSCRAPE_USER='your_username'
export PROXYSCRAPE_PASS='your_password'
export PROXYSCRAPE_ENDPOINT='http://proxy.proxyscrape.com:8080'

Затем в settings.py добавьте:

import os

PROXYSCRAPE_USER = os.getenv('PROXYSCRAPE_USER')
PROXYSCRAPE_PASS = os.getenv('PROXYSCRAPE_PASS')
PROXYSCRAPE_ENDPOINT = os.getenv('PROXYSCRAPE_ENDPOINT')

Шаг 3: Создайте промежуточное ПО ротации

Создайте новый файл proxyscrape_scraper/middlewares.py и определите промежуточное ПО, которое:

  • Выбирает прокси из списка или использует ваш ротационный эндпоинт.
  • Внедряет учетные данные в URL прокси.
  • Повторяет попытки при HTTP-статусах, связанных с блокировкой.
# proxyscrape_scraper/middlewares.py
import random
import logging
from scrapy import signals
from scrapy.exceptions import NotConfigured

class ProxyScrapeRotationMiddleware:
    def __init__(self, proxy_list, credentials):
        self.proxy_list = proxy_list
        self.credentials = credentials
        self.logger = logging.getLogger(__name__)

    @classmethod
    def from_crawler(cls, crawler):
        proxy_list = crawler.settings.getlist('PROXY_LIST')
        credentials = (
            crawler.settings.get('PROXYSCRAPE_USER'),
            crawler.settings.get('PROXYSCRAPE_PASS'),
        )
        if not proxy_list:
            raise NotConfigured('PROXY_LIST is empty')
        return cls(proxy_list, credentials)

    def process_request(self, request, spider):
        proxy = random.choice(self.proxy_list)
        user, password = self.credentials
        if user and password:
            proxy = proxy.replace('://', f'://{user}:{password}@')
        request.meta['proxy'] = proxy
        self.logger.debug(f'Using proxy: {proxy}')

    def process_response(self, request, response, spider):
        if response.status in [403, 429, 503]:
            self.logger.warning(
                f'Ban detected with status {response.status} on {request.url}'
            )
            request.meta['proxy'] = None
            return request.replace(dont_filter=True)
        return response

Шаг 4: Настройте параметры для ротации и повторных попыток

В settings.py определите список прокси, включите промежуточное ПО и настройте поведение повторных попыток.

# settings.py
PROXY_LIST = [
    'http://proxy1.proxyscrape.com:8080',
    'socks5://proxy2.proxyscrape.com:1080',
    # Add more endpoints from your ProxyScrape dashboard
]

DOWNLOADER_MIDDLEWARES = {
    'proxyscrape_scraper.middlewares.ProxyScrapeRotationMiddleware': 543,
    'scrapy.downloadermiddlewares.retry.RetryMiddleware': 550,
}

RETRY_ENABLED = True
RETRY_TIMES = 3
RETRY_HTTP_CODES = [403, 429, 500, 502, 503, 504]

Шаг 5: Необязательно — Липкие сессии с идентификаторами сессий

Если ваш тариф ProxyScrape поддерживает липкие сессии через параметры имени пользователя, вы можете добавить идентификатор сессии к имени пользователя. Проверьте точный синтаксис в панели управления ProxyScrape (часто что-то вроде username-session-abc123).

# Inside process_request, replace the username logic:
session_id = ''.join(random.choices('abcdef0123456789', k=8))
user = f'{self.credentials[0]}-session-{session_id}'
proxy = proxy.replace('://', f'://{user}:{self.credentials[1]}@')

Используйте липкие сессии, когда нужно сохранять один и тот же IP для нескольких запросов к одному домену, например во время входа в систему или многошагового оформления заказа.

Шаг 6: Протестируйте ваш ротационный скрейпер

Создайте простого паука, чтобы убедиться, что запросы идут через разные прокси.

# proxyscrape_scraper/spiders/ip_test.py
import scrapy

class IpTestSpider(scrapy.Spider):
    name = 'ip_test'
    start_urls = ['https://httpbin.org/ip']

    def parse(self, response):
        yield {'ip': response.json()['origin']}

Запустите паука и сохраните результаты:

scrapy crawl ip_test -o ips.json

Откройте ips.json и убедитесь, что значения ip различаются. Если вы видите один и тот же IP повторно, проверьте ваш PROXY_LIST или конфигурацию ротационного эндпоинта.

Выбор подходящего типа прокси ProxyScrape для Scrapy

Тип прокси Лучше всего подходит для Ротация Липкие сессии Поддержка протоколов
Резидентные Общий веб-скрейпинг, геотаргетированные данные Ротационный эндпоинт или список Обычно доступны через идентификаторы сессий HTTP, SOCKS5
Датацентровые Высокоскоростной скрейпинг незащищенных сайтов Ротационный эндпоинт или список Часто статические HTTP, SOCKS5
Мобильные Сайты только для мобильных устройств, социальные сети, тестирование приложений Ротационный эндпоинт Обычно доступны HTTP, SOCKS5

Устранение неполадок

  • Ошибки аутентификации (407 Proxy Authentication Required): Перепроверьте имя пользователя и пароль. Если используете ротационный эндпоинт, убедитесь, что учетные данные правильно встроены как user:pass@host:port.
  • Таймауты соединения: Попробуйте переключиться с HTTP на SOCKS5 или наоборот. Некоторые сайты более агрессивно блокируют один из протоколов. Также проверьте, что ваш брандмауэр разрешает исходящий трафик на порту прокси.
  • Блокировки не обнаруживаются: Если вы все еще получаете CAPTCHA или пустые данные, расширьте обнаружение блокировок, чтобы искать признаки CAPTCHA в теле ответа (например, наличие captcha в HTML). Вы также можете снизить частоту запросов и увеличить DOWNLOAD_DELAY.
  • Ошибки SOCKS5: Scrapy требует библиотеку requests с поддержкой SOCKS для SOCKS5-прокси. Установите ее с помощью pip install requests[socks], если видите Missing dependencies for SOCKS support.
  • Липкие сессии не работают: Уточните точный формат параметра сессии в панели управления ProxyScrape. В некоторых тарифах используется username-session-{id}, в других — отдельное поле пароля.

Итог

Теперь у вас есть готовое к использованию в продакшене промежуточное ПО Scrapy, которое выполняет ротацию прокси ProxyScrape, повторяет попытки при блокировках и опционально поддерживает липкие сессии. Эта настройка позволяет масштабировать ваши проекты скрейпинга, не беспокоясь об ограничениях скорости или блокировках IP. Для лучших результатов сочетайте ротационные резидентные прокси с консервативной задержкой загрузки и отслеживайте показатели успеха. Корректируйте ваш PROXY_LIST и логику повторных попыток по мере изменения целей скрейпинга.