HTTP прокси — это промежуточный сервер, который принимает HTTP-запросы от клиента и перенаправляет их к целевому серверу. При этом целевой сервер видит IP-адрес прокси, а не ваш реальный адрес. Использование прокси в Scrapy позволяет избежать блокировок по IP, географических ограничений и повысить анонимность при парсинге веб-сайтов. Данная статья посвящена настройке прокси в Scrapy с использованием middleware и реализации ротации прокси.
Настройка прокси в Scrapy с использованием Middleware
Scrapy middleware — это мощный механизм для обработки запросов и ответов. Для использования прокси мы создадим middleware, который будет добавлять прокси к каждому запросу.
Создание Middleware для прокси
-
Создайте файл
middlewares.pyв директории вашего проекта Scrapy. Если он уже существует, просто добавьте новый класс. -
В
middlewares.pyопределите класс, который будет обрабатывать запросы.
import random
class ProxyMiddleware:
def __init__(self, proxy_list):
self.proxy_list = proxy_list
@classmethod
def from_crawler(cls, crawler):
return cls(
proxy_list=crawler.settings.getlist('PROXY_LIST')
)
def process_request(self, request, spider):
proxy = random.choice(self.proxy_list)
request.meta['proxy'] = proxy
print(f"Using proxy: {proxy}") # Optional logging
def process_response(self, request, response, spider):
# Optional: Handle response codes and retry failed requests
if response.status >= 400:
print(f"Proxy {request.meta['proxy']} failed with status {response.status}. Retrying...")
return self._retry_request(request, spider)
return response
def process_exception(self, request, exception, spider):
# Optional: Handle exceptions and retry failed requests
print(f"Proxy {request.meta['proxy']} caused exception {exception}. Retrying...")
return self._retry_request(request, spider)
def _retry_request(self, request, spider):
retries = request.meta.get('retry_times', 0) + 1
if retries <= spider.settings.get('RETRY_TIMES', 2):
request.meta['retry_times'] = retries
return request.copy()
else:
print(f"Max retries reached for {request.url} with proxy {request.meta['proxy']}")
return None
В этом коде:
__init__: Инициализирует middleware, получая список прокси.from_crawler: Получает список прокси из настроек Scrapy (settings.py).process_request: Выбирает случайный прокси из списка и добавляет его в метаданные запроса (request.meta['proxy']).process_response: Проверяет статус ответа и, если он указывает на ошибку (>= 400), пытается повторить запрос.process_exception: Обрабатывает исключения, возникающие при использовании прокси, и пытается повторить запрос._retry_request: Функция, которая повторяет запрос.
Активация Middleware
- В файле
settings.pyвашего проекта Scrapy добавьте созданный middleware вDOWNLOADER_MIDDLEWARES. Укажите приоритет middleware. Чем меньше число, тем выше приоритет.
DOWNLOADER_MIDDLEWARES = {
'your_project_name.middlewares.ProxyMiddleware': 750,
}
Замените your_project_name на имя вашего проекта Scrapy.
- Также в
settings.pyопределите список прокси:
PROXY_LIST = [
'http://user1:pass1@ip1:port1',
'http://user2:pass2@ip2:port2',
'http://user3:pass3@ip3:port3',
# ... другие прокси
]
Убедитесь, что прокси указаны в правильном формате (с аутентификацией, если требуется).
- Настройте параметры повторных попыток (опционально):
RETRY_TIMES = 3 # Number of times to retry failed requests
Пример использования
После настройки middleware прокси будут автоматически использоваться для всех запросов, выполняемых вашим spider'ом. Вам не нужно вносить какие-либо изменения в код spider'а.
Ротация прокси
Ротация прокси — это процесс автоматической смены прокси-серверов после определенного количества запросов или при возникновении ошибок. Это помогает избежать блокировок и повышает стабильность парсинга. В примере выше уже реализована базовая ротация, выбирая случайный прокси из списка. Для более продвинутой ротации можно использовать следующие подходы:
Ведение списка "живых" прокси
Можно реализовать механизм проверки прокси на работоспособность и исключать нерабочие прокси из списка.
-
Проверка прокси: Создайте функцию, которая отправляет запрос через прокси на проверочный сайт (например,
httpbin.org/ip) и проверяет, что IP-адрес ответа соответствует IP-адресу прокси. -
Обновление списка прокси: Периодически запускайте функцию проверки и обновляйте список
PROXY_LISTвsettings.py. Можно использовать Scrapy scheduler для этого. -
Обработка ошибок: В middleware (
process_responseиprocess_exception) отслеживайте ошибки, связанные с прокси, и временно исключайте "проблемные" прокси из списка, чтобы избежать повторных попыток использования нерабочих прокси.
Использование внешних сервисов ротации прокси
Существуют платные сервисы, предоставляющие API для получения списка рабочих прокси и автоматической ротации. Использование таких сервисов упрощает настройку и обслуживание прокси, но требует финансовых затрат.
Пример использования сервиса с API (псевдокод):
# В settings.py:
PROXY_API_URL = "https://api.example.com/get_proxy"
# В middlewares.py:
import requests
class ProxyMiddleware:
def process_request(self, request, spider):
try:
response = requests.get(spider.settings['PROXY_API_URL'])
response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
proxy = response.text.strip() # Assuming the API returns a single proxy
request.meta['proxy'] = proxy
print(f"Using proxy from API: {proxy}")
except requests.exceptions.RequestException as e:
print(f"Error fetching proxy from API: {e}")
# Handle the error (e.g., use a default proxy or skip this request)
# It's crucial to handle API errors gracefully!
return None
Важно: Обработка ошибок при запросах к API прокси очень важна. Необходимо предусмотреть ситуации, когда API недоступен или возвращает ошибки.
Сравнение подходов к ротации прокси
| Характеристика | Собственный список прокси | Внешний сервис ротации |
|---|---|---|
| Стоимость | Низкая (стоимость прокси) | Высокая (плата за сервис) |
| Сложность настройки | Высокая | Низкая |
| Обслуживание | Высокое | Низкое |
| Гибкость | Высокая | Ограниченная |
| Надежность | Зависит от качества прокси | Высокая |
Обработка ошибок и повторные попытки
Важно правильно обрабатывать ошибки, возникающие при использовании прокси, такие как таймауты, ошибки соединения и HTTP-ошибки. В примере кода middleware уже реализованы базовые механизмы повторных попыток (process_response, process_exception и _retry_request). Рекомендуется настроить параметры повторных попыток (RETRY_TIMES) в settings.py и логировать ошибки для анализа и отладки.
Заключение
Настройка прокси в Scrapy с использованием middleware и ротации — важный шаг для успешного парсинга веб-сайтов и обхода ограничений. Правильная настройка и обработка ошибок позволяют повысить надежность и стабильность работы spider'а. Выбор подхода к ротации прокси зависит от ваших потребностей и бюджета. Собственный список прокси требует больше усилий по обслуживанию, но обеспечивает большую гибкость и контроль. Внешние сервисы ротации прокси упрощают настройку и обслуживание, но требуют финансовых затрат.
Полезные ссылки
- Scrapy Documentation: https://docs.scrapy.org/en/latest/{rel="nofollow"}
- HTTPBin: https://httpbin.org/{rel="nofollow"} - Useful for testing HTTP requests.
- Free Proxy Lists (Use with caution): Many websites offer free proxy lists, but their reliability and security are often questionable. Use them at your own risk. Examples: https://free-proxy-list.net/{rel="nofollow"}, https://www.sslproxies.org/{rel="nofollow"}
- Proxy Services: https://oxylabs.io/{rel="nofollow"}, https://brightdata.com/{rel="nofollow"}, https://smartproxy.com/{rel="nofollow"} (Examples of commercial proxy providers).