HTTP-проксі-сервер діє як посередник між вашим скриптом веб-скрейпінгу та цільовим веб-сайтом. Замість того, щоб ваш Scrapy-павук підключався безпосередньо до цілі, він підключається до проксі-сервера, який потім пересилає запит до цілі. Це дозволяє маскувати вашу IP-адресу, обходити географічні обмеження та уникати блокування веб-сайтами, що застосовують заходи проти скрейпінгу. Ця стаття надає практичний посібник зі встановлення та ротації проксі за допомогою Scrapy middleware.
Налаштування проксі в Scrapy за допомогою Middleware
Система middleware Scrapy надає гнучкий спосіб обробки запитів та відповідей. Ми можемо використовувати цю систему для реалізації підтримки проксі. Процес включає створення власного middleware, яке перехоплює запити та призначає їм проксі-сервер.
Створення власного Proxy Middleware
Спершу створіть новий файл Python (наприклад, proxy_middleware.py) у вашому проекті Scrapy. Цей файл міститиме код для вашого власного проксі-middleware.
import random
class ProxyMiddleware:
def __init__(self, proxies):
self.proxies = proxies
@classmethod
def from_crawler(cls, crawler):
return cls(crawler.settings.getlist('PROXIES'))
def process_request(self, request, spider):
proxy = random.choice(self.proxies)
request.meta['proxy'] = proxy
print(f"Using proxy: {proxy}")
def process_response(self, request, response, spider):
# Optional: Handle response codes to retry with a different proxy
if response.status in [403, 429]:
print(f"Proxy {request.meta['proxy']} blocked, retrying with another proxy.")
return self._retry_request(request, spider)
return response
def _retry_request(self, request, spider):
proxy = random.choice(self.proxies)
request.meta['proxy'] = proxy
new_request = request.copy()
return new_request
Пояснення:
__init__(self, proxies): Конструктор приймає список проксі як вхідні дані.from_crawler(cls, crawler): Цей метод класу використовується Scrapy для створення екземпляра middleware. Він отримує список проксі з налаштувань Scrapy.process_request(self, request, spider): Цей метод викликається перед тим, як Scrapy надсилає запит. Він випадковим чином вибирає проксі зі списку та призначає його атрибутуmeta['proxy']запиту. Це вказує Scrapy використовувати вказаний проксі для цього запиту.process_response(self, request, response, spider): Цей метод дозволяє обробляти відповідь, отриману від сервера. Тут він перевіряє коди стану, такі як 403 (Forbidden) або 429 (Too Many Requests), які часто вказують на те, що проксі заблоковано. Якщо знайдено код блокування, він повторює запит з іншим проксі._retry_request(self, request, spider): Цей метод створює новий запит з призначеним іншим проксі.
Налаштування параметрів Scrapy
Далі вам потрібно налаштувати параметри Scrapy, щоб увімкнути middleware та надати список проксі. Відкрийте файл settings.py і додайте наступне:
# settings.py
# Enable the ProxyMiddleware
DOWNLOADER_MIDDLEWARES = {
'your_project_name.proxy_middleware.ProxyMiddleware': 350, # Adjust priority as needed
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': None, # Disable the default HttpProxyMiddleware
}
# List of proxies
PROXIES = [
'http://user1:pass1@proxy1.example.com:8080',
'http://user2:pass2@proxy2.example.com:8080',
'http://user3:pass3@proxy3.example.com:8080',
'https://user4:pass4@proxy4.example.com:8080',
]
# Retry many times since proxies often fail
RETRY_TIMES = 10
# Retry on most error codes since proxies fail a lot
RETRY_HTTP_CODES = [500, 502, 503, 504, 400, 408]
# Disable default user agent middleware and use a custom one
DOWNLOADER_MIDDLEWARES.update({
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
'scrapy_user_agents.middlewares.RandomUserAgentMiddleware': 400,
})
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
Пояснення:
DOWNLOADER_MIDDLEWARES: Цей словник вмикає та налаштовує downloader middlewares. Ключ — це шлях до вашого класу middleware, а значення — пріоритет middleware. Менші числа вказують на вищий пріоритет (middleware виконується раніше). СтандартнийHttpProxyMiddlewareвимкнено, щоб уникнути конфліктів з власним middleware.PROXIES: Цей список містить проксі-сервери, які ви хочете використовувати. Формат:protocol://user:password@host:port. Можна використовувати як HTTP, так і HTTPS проксі. Якщо ім'я користувача та пароль не потрібні, формат простоprotocol://host:port.RETRY_TIMESтаRETRY_HTTP_CODES: Ці налаштування конфігурують middleware повторних спроб Scrapy. Оскільки проксі можуть бути ненадійними, рекомендується збільшити кількість повторних спроб та включити поширені коди помилок HTTP, які можуть вказувати на проблему з проксі.DOWNLOADER_MIDDLEWARES.update(...): Цей розділ вимикає стандартний middleware User Agent та вмикаєscrapy_user_agentsдля ротації User Agents. Це допомагає запобігти легкому ідентифікуванню вашого скрейпера. Вам потрібно буде встановитиscrapy_user_agentsза допомогоюpip install scrapy-user-agents.
Запуск павука
Тепер ви можете запускати свого Scrapy-павука як зазвичай. Middleware автоматично призначить проксі кожному запиту.
scrapy crawl your_spider_name
Стратегії ротації проксі
Ротація проксі є критично важливою для запобігання блокуванню вашого скрейпера. Ось деякі поширені стратегії:
- Випадковий вибір: Як реалізовано в прикладі вище, випадковий вибір проксі зі списку для кожного запиту. Це найпростіший підхід, але він може бути не найефективнішим.
- Послідовна ротація: Циклічне перебирання списку проксі в послідовному порядку. Це може бути корисно, якщо ви хочете переконатися, що кожен проксі використовується однакову кількість разів.
- Інтелектуальна ротація: Реалізація логіки для відстеження продуктивності кожного проксі та пріоритезації проксі, які працюють добре. Це може включати моніторинг часу відгуку, частоти помилок та інших метрик.
- Використання Proxy API: Використання API проксі-сервісу, який автоматично обробляє ротацію та керування проксі. Ці сервіси часто надають такі функції, як геотаргетинг та керування репутацією IP-адрес.
Послідовна ротація проксі
Ось приклад реалізації послідовної ротації проксі у вашому middleware:
import itertools
class SequentialProxyMiddleware:
def __init__(self, proxies):
self.proxies = itertools.cycle(proxies) # Use cycle to rotate proxies
@classmethod
def from_crawler(cls, crawler):
return cls(crawler.settings.getlist('PROXIES'))
def process_request(self, request, spider):
proxy = next(self.proxies) # Get the next proxy from the cycle
request.meta['proxy'] = proxy
print(f"Using proxy: {proxy}")
def process_response(self, request, response, spider):
if response.status in [403, 429]:
print(f"Proxy {request.meta['proxy']} blocked, rotating to the next proxy.")
return self._retry_request(request, spider)
return response
def _retry_request(self, request, spider):
proxy = next(self.proxies)
request.meta['proxy'] = proxy
new_request = request.copy()
return new_request
Ключова зміна:
itertools.cycle(proxies): Це створює ітератор, який нескінченно перебирає список проксі. Функціяnext()використовується для отримання наступного проксі в послідовності.
Не забудьте оновити налаштування DOWNLOADER_MIDDLEWARES, щоб вказати на SequentialProxyMiddleware.
Інтеграція з Proxy API
Інтеграція з Proxy API зазвичай передбачає надсилання запитів до API для отримання проксі та обробку автентифікації та відповідей на помилки API. Специфіка залежатиме від обраного вами API. Багато провайдерів проксі пропонують Python SDK для спрощення цього процесу.
Типи проксі
Ось порівняння різних типів проксі:
| Функція | HTTP Проксі | HTTPS Проксі | SOCKS Проксі |
|---|---|---|---|
| Протокол | HTTP | HTTPS | SOCKS (різні версії) |
| Шифрування | Немає шифрування між клієнтом і проксі | Шифрування між клієнтом і проксі | Шифрування залежить від версії SOCKS |
| Випадки використання | Веб-перегляд, скрейпінг HTTP-сайтів | Веб-перегляд, скрейпінг HTTPS-сайтів | Загального призначення, підтримує різні протоколи |
| Анонімність | Може бути менш анонімним | Може бути більш анонімним | Може бути дуже анонімним |
| Конфігурація | Зазвичай налаштовується у веб-браузерах | Зазвичай налаштовується у веб-браузерах | Потребує SOCKS-клієнта або підтримки бібліотеки |
| Приклад URL | http://host:port |
https://host:port |
socks5://host:port або socks4://host:port |
| Автентифікація | Базова автентифікація (ім'я користувача/пароль) | Базова автентифікація (ім'я користувача/пароль) | Підтримується автентифікація за ім'ям користувача/паролем |
Поширені проблеми та усунення несправностей
- Проксі не працюють: Переконайтеся, що проксі-сервер онлайн і доступний. Перевірте облікові дані автентифікації проксі (ім'я користувача та пароль). Переконайтеся, що формат проксі у
settings.pyправильний. - Заблоковані проксі: Впровадьте ротацію проксі та розгляньте можливість використання проксі-сервісу з великим пулом IP-адрес. Моніторте коди відповідей (403, 429) та автоматично повторюйте запити з різними проксі.
- Низька продуктивність: Вибирайте проксі, які географічно близькі до цільового сервера. Тестуйте різних провайдерів проксі, щоб знайти того, хто забезпечує надійну продуктивність.
- Помилки HTTPS: Переконайтеся, що ваш проксі підтримує HTTPS-з'єднання. Деякі HTTP-проксі підтримують лише HTTP-трафік.
- Витоки DNS: Використовуйте SOCKS-проксі або налаштуйте свою систему на використання DNS-сервера проксі, щоб запобігти витокам DNS.
Висновок
Налаштування та ротація проксі в Scrapy є важливими для створення надійних та стабільних веб-скрейперів. Використовуючи власні middleware, впроваджуючи ефективні стратегії ротації та розуміючи різні типи проксі, ви можете значно зменшити ризик блокування та покращити продуктивність ваших проектів скрейпінгу. Пам'ятайте, що потрібно постійно моніторити ваші проксі та адаптувати свою стратегію за необхідності, щоб підтримувати оптимальну ефективність скрейпінгу.
Не забувайте регулярно тестувати свої проксі та моніторити їхню продуктивність, щоб переконатися, що ваш скрейпер продовжує ефективно функціонувати. Розгляньте можливість використання сервісу керування проксі для більш розширених функцій та легшого керування.