Scarnox · Blog

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

Ротируемый прокси меняет IP-адрес, с которого выходит ваш трафик, либо на каждом запросе, либо после заданного интервала. Это один из самых распространенных инструментов парсинга и один из самых неправильно используемых. Ротируете слишком мало — один адрес получит ограничение частоты. Ротируете слишком много — трафик перестанет походить на посетителя. Это руководство объясняет две модели ротации, показывает рабочую настройку на Python с повторами для мертвых прокси и рассказывает, как поле прокси вписывается в решение капчи.

Ротация против закрепленных сессий

Есть два способа, которыми сервис ротируемых прокси выдает адреса:

Настоящий посетитель сохраняет один адрес на весь визит. Закрепленные сессии повторяют это поведение, поэтому они обычно лучший вариант по умолчанию, когда сайт использует cookie или сессии. Ротацию на каждый запрос используйте для обхода без состояния.

Базовый ротируемый пул на Python

Пример ниже хранит пул URL прокси, переключается между ними и переходит к следующему, если один не работает. Храните учетные данные в переменных окружения, никогда в исходном коде.

import itertools
import os
import requests

# URL прокси берутся из окружения, например:
# PROXY_POOL="http://user:pass@203.0.113.10:8080,http://user:pass@203.0.113.11:8080"
PROXIES = [p.strip() for p in os.environ.get("PROXY_POOL", "").split(",") if p.strip()]
rotation = itertools.cycle(PROXIES)

def fetch(url: str, max_tries: int = 3) -> requests.Response:
    last_error = None
    for _ in range(max_tries):
        proxy = next(rotation)
        try:
            r = requests.get(
                url,
                proxies={"http": proxy, "https": proxy},
                timeout=30,
            )
            if r.status_code == 407:  # прокси не прошел аутентификацию
                raise requests.RequestException("proxy auth rejected")
            return r
        except requests.RequestException as exc:
            last_error = exc  # мертвый или медленный прокси: пробуем следующий
    raise RuntimeError(f"all attempts failed for {url}: {last_error}")

Здесь важны два момента. Во-первых, мертвый прокси нужно повторять на другом адресе, а не на том же. Во-вторых, запрос, который падает с ошибкой аутентификации, должен остановиться и быть зафиксирован, а не перебирать весь пул.

Отслеживайте здоровье прокси

Простая круговая ротация продолжает отправлять трафик на прокси, который начал падать. Ведите простую оценку для каждого адреса: считайте недавние сбои и исключайте адрес из пула на период охлаждения, когда он превышает порог. Затем возвращайте его позже и снова наблюдайте. Ваш парсер тратит запросы на здоровую часть пула.

Логируйте прокси, использованный для каждого результата. Когда сайт начинает возвращать блокировки, вы захотите знать, виноват один адрес, один регион или весь пул.

Пауза для пула

Ротация распределяет нагрузку по адресам, но у каждого адреса все равно есть своя частота. Задайте задержку для каждого адреса и глобальный лимит запросов в секунду по всему пулу. Ротация — не разрешение отправлять больше трафика. Это способ держать трафик с одного адреса в разумных пределах.

Частые ошибки

Большинство проблем с ротацией возникает из нескольких привычек. Смена адреса посреди входа в систему или оформления заказа ломает сессию и делает сайт подозрительным. Ответ 429 — это ограничение частоты на стороне сайта, а не сломанный прокси, поэтому переключение на новый адрес и немедленный повтор лишь распространяют проблему. Смена адреса на каждом запросе при сохранении тех же cookie тоже непоследовательна, потому что cookie выданы другому посетителю. Наконец, пул, который никогда не проверяется, незаметно заполняется мертвыми адресами, и уровень ошибок растет без явной причины. Проверяйте пул по расписанию и удаляйте то, что не работает.

Прокси и решение капчи

Некоторые задачи с капчей могут использовать прокси, который использует ваш парсер. Вы передаете его в необязательном поле proxy в формате http://user:pass@host:port, и решение выполняется по тому же сетевому пути, что и запрос страницы. Задачи без прокси пропускают это поле полностью. Какой вариант выбрать, зависит от того, привязывает ли сайт капчу к сетевому адресу, и этот компромисс объяснен в прокси или без прокси при решении капчи.

Два практических момента:

Живой тип капчи в Scarnox сегодня — PopularCaptcha. Руководство по PopularCaptcha на Python показывает запрос и то, как отправить полученный токен.

Выбор прокси

Тип адресов, которые вы ротируете, важен не меньше самой ротации. Адреса дата-центров быстрые и дешевые за запрос, но часто получают низкую оценку. Резидентские адреса получают лучшую оценку и работают медленнее. Руководство резидентские и датацентровые прокси сравнивает их подробно, и его советы применимы к пулу, который вы строите здесь.

Ответственный парсинг

Следующие шаги

Начните с бесплатного пробного баланса, карта не нужна: создайте аккаунт и протестируйте поток PopularCaptcha со своим прокси. Актуальные тарифы — на странице цен.