Продвинутая ротация ProxyScrape в Scrapy: пользовательское промежуточное ПО загрузчика с повторными попытками и обнаружением блокировок
Создайте пользовательское промежуточное ПО загрузчика Scrapy, которое выполняет ротацию резидентных и датацентровых прокси ProxyScrape, обрабатывает повторные попытки и обнаруживает блокировки для надежного крупномасштабного скрейпинга.
Обзор
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 и логику повторных попыток по мере изменения целей скрейпинга.