Как настроить ротацию прокси для автоматизации задач

Ты запускаешь парсер. Первые 50 запросов проходят. На 51-м — капча. На 80-м — бан. Знакомо?

Проблема почти всегда в одном: ты долбишь сервер с одного IP. Решение — ротация прокси. Но между «я знаю, что нужно менять IP» и «у меня работает стабильная система на 100 000 запросов в сутки» — пропасть. Прежде чем настраивать ротацию, нужно выбрать провайдера с поддержкой этой функции. Фильтр по типу ротации доступен в рейтингах на ТОПроксиЛаб — это сэкономит часы, которые ты потратил бы на тестирование провайдеров вслепую.

Дальше разберёмся, как это всё настроить руками.

Что такое ротация и зачем она нужна

Ротация прокси — это автоматическая смена IP-адреса между запросами. Или по таймеру. Или по триггеру. Суть одна: целевой сервер видит не одного назойливого бота, а поток разных «пользователей».

Без ротации любая автоматизация упирается в потолок. У каждого сайта есть rate limits. У кого-то жёсткие — 10 запросов в минуту с одного IP. У кого-то мягкие — 500 запросов, потом мягкий бан на час. Но потолок есть всегда.

Ротация этот потолок убирает. Не обходит — именно убирает. Потому что каждый IP тратит только малую часть своего лимита.

Три модели ротации

Не все ротации одинаковые. Я выделяю три модели, и выбор между ними зависит от задачи.

  • Ротация на каждый запрос. Каждый HTTP-запрос уходит с нового IP. Самый агрессивный вариант. Подходит для массового парсинга, когда тебе не нужно сохранять сессию. Запросил страницу товара — получил — забыл. Следующий товар — другой IP.
  • Sticky sessions (липкие сессии). IP держится 1-10-30 минут, потом меняется. Нужно, когда сайт отслеживает сессию. Например, ты парсишь каталог с пагинацией — страница 1, 2, 3. Если каждая страница приходит с нового IP, сайт может сломать навигацию или показать капчу. Sticky session решает это: ты «сидишь» на одном IP достаточно долго, чтобы завершить цепочку действий.
  • Ротация по триггеру. IP меняется не по таймеру, а по событию. Получил 403? Сменил IP. Увидел капчу? Сменил IP. Таймаут? Сменил. Самая умная модель, но требует кода.

Как это устроено на стороне провайдера

Большинство прокси-сервисов дают тебе один gateway-адрес. Что-то вроде gate.provider.com:7777. Ты отправляешь запрос на этот адрес, а провайдер сам выбирает, через какой IP его прокинуть.

Управление обычно через параметры в логине. Выглядит примерно так:

user-client123-session-abc123-country-us:password@gate.provider.com:7777

Тут session-abc123 — это идентификатор sticky-сессии. Пока ты передаёшь один и тот же session ID, провайдер маршрутизирует через один IP. Сменил ID — получил новый IP.

У каждого провайдера синтаксис свой. Bright Data делает через session-rand12345. Oxylabs через sessid-abc. Некоторые мелкие провайдеры вообще не поддерживают sticky sessions и ротируют принудительно на каждый запрос. Проверяй до покупки.

Настройка ротации в Python

Самый простой вариант — список прокси и random.choice.

import random
import requests

proxies_list = [
    "http://user:pass@ip1:port",
    "http://user:pass@ip2:port",
    "http://user:pass@ip3:port",
]
def get_page(url):
    proxy = random.choice(proxies_list)
    return requests.get(url, proxies={"http": proxy, "https": proxy}, timeout=10)

Работает? Работает. Для 100 запросов в день хватит. Для серьёзной нагрузки — нет. Потому что тут нет обработки ошибок, нет бан-листа для мёртвых прокси, нет контроля за тем, какой IP сколько раз использовался.

Вот версия, которую я реально использую в продакшене:

import random
import time
import requests
from collections import defaultdict
from itertools import cycle

class ProxyRotator:
    def __init__(self, proxies):
        self.proxies = proxies
        self.failed = set()
        self.usage_count = defaultdict(int)
    
    def get_proxy(self):
        available = [p for p in self.proxies if p not in self.failed]
        if not available:
            self.failed.clear()  # сброс, если все "умерли"
            available = self.proxies
        # берём наименее использованный
        proxy = min(available, key=lambda p: self.usage_count[p])
        self.usage_count[proxy] += 1
        return proxy
    
    def mark_failed(self, proxy):
        self.failed.add(proxy)
    
    def fetch(self, url, max_retries=3):
        for attempt in range(max_retries):
            proxy = self.get_proxy()
            try:
                resp = requests.get(
                    url,
                    proxies={"http": proxy, "https": proxy},
                    timeout=15
                )
                if resp.status_code == 403:
                    self.mark_failed(proxy)
                    continue
                return resp
            except requests.RequestException:
                self.mark_failed(proxy)
                time.sleep(1)
        return None

Что тут происходит: ротатор выбирает наименее использованный прокси, при ошибке или бане помечает его как мёртвый, при исчерпании пула — сбрасывает бан-лист. Грубо, но надёжно.

Настройка в Scrapy

Scrapy — другая история. Там прокси подключаются через middleware.

# middlewares.py
import random

class RotatingProxyMiddleware:
    def __init__(self):
        self.proxies = [
            "http://user:pass@ip1:port",
            "http://user:pass@ip2:port",
            "http://user:pass@ip3:port",
        ]
    
    def process_request(self, request, spider):
        request.meta['proxy'] = random.choice(self.proxies)

В settings.py:

DOWNLOADER_MIDDLEWARES = {
    'myproject.middlewares.RotatingProxyMiddleware': 610,
}

Для Scrapy есть готовая библиотека scrapy-rotating-proxies. Ставишь, кидаешь список прокси в настройки, она сама управляет ротацией и банит мёртвые. Работает нормально. Я пользовался ей года полтора, потом написал своё, потому что хотел более тонкий контроль. Но для старта — отлично.

Backconnect-прокси vs список IP

Тут развилка, и она принципиальная.

  1. Список IP — это когда провайдер даёт тебе файл с 500 или 1000 адресами. Ты сам управляешь ротацией. Плюс — полный контроль. Минус — IP «горят», и тебе нужно самому отслеживать, какие ещё живые.
  2. Backconnect (вращающийся шлюз) — один адрес, провайдер ротирует за тебя. Плюс — не нужно писать логику ротации, пул обычно огромный (миллионы IP у крупных провайдеров). Минус — меньше контроля. И если провайдер лагает, ты ничего не можешь сделать, кроме как ждать.

Для большинства задач backconnect удобнее. Писать свой ротатор поверх списка IP имеет смысл, когда нужен контроль до секунды: например, ты точно знаешь, что на конкретном сайте нужно менять IP каждые 47 запросов (да, бывают такие кейсы).

Задержки: искусство быть похожим на человека

Ротация без задержек — деньги на ветер. Серьёзно.

Ты можешь иметь пул из 10 000 резидентных IP, но если делаешь 50 запросов в секунду к одному домену, антибот-система увидит аномалию. Не по IP — по паттерну. Слишком ровный интервал. Слишком много запросов к одним и тем же эндпоинтам. Нет пауз на «чтение».

Минимум, который я ставлю:

import random
import time

def human_delay():
    base = random.uniform(1.5, 4.0)
    # иногда "пользователь" отвлекается
    if random.random() < 0.1:
        base += random.uniform(5, 15)
    time.sleep(base)

10% запросов с длинной паузой. Это имитирует реального человека, который отвлёкся на телефон или пошёл за кофе. Мелочь, а процент банов падает заметно.

Гео-ротация

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

Настраивается обычно через параметр в логине:

user-client123-country-de:password@gate.provider.com:7777

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

Мониторинг: как понять, что что-то пошло не так

Ротацию настроил, парсер запустил, ушёл спать. Утром проснулся — в базе мусор. Или пусто. Бывало.

Что мониторю:

  • Процент успешных запросов. Падает ниже 80% — алерт. Значит, прокси горят или сайт поменял защиту.
  • Среднее время ответа. Резко выросло — прокси тормозят или сайт троттлит.
  • Количество уникальных IP за час. Если ротатор работает, а уникальных IP три штуки — что-то сломалось.
  • Процент капч. Поймал капчу — это не бан, но предупреждение. Если капч больше 5% от запросов — пора менять стратегию.

Я всё это кидаю в Grafana через Prometheus. Можно проще — логи в файл и скрипт, который парсит их раз в час. Главное — не летать вслепую.

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

  • Использовать бесплатные прокси. Списки из интернета. Они мёртвые на 90%. Оставшиеся 10% медленные и уже в бан-листах всех крупных сайтов. И через них может течь твой трафик в открытом виде. Бесплатный прокси — это чужой сервер, и ты не знаешь, кто его поставил.
  • Не обрабатывать ошибки. Запрос упал — повторить с тем же IP. Гениально. IP уже забанен, и ты делаешь ещё 5 попыток с ним, теряя время и деньги (если платишь за трафик).
  • Один провайдер. У него упал пул, и твой бизнес-процесс встал. Я всегда держу минимум два провайдера. Основной и резервный. Переключение автоматическое по проценту ошибок.
  • Ротация без смены фингерпринта. Меняешь IP, а User-Agent один и тот же. Или TLS-фингерпринт. Сайт видит: разные IP, но один и тот же «браузер». Подозрительно? Ещё как.

Когда ротация не нужна

Не каждая задача требует ротации.

Если ты делаешь 10-20 запросов в день к API, у которого лимит 1000 — зачем тебе прокси? Прямой запрос с сервера сработает.

Если работаешь с сайтом, у которого есть официальный API — используй его. Серьёзно. У Amazon есть Product Advertising API. У Ozon есть Seller API. Да, там свои лимиты и ограничения, но тебя не забанят и не подадут в суд.

Ротация — это инструмент для масштаба. Десятки тысяч запросов. Сотни тысяч. Миллионы. Если у тебя не те объёмы — не усложняй.

Итого

Настройка ротации прокси — не rocket science. Базовую версию можно поднять за час. Но стабильная система, которая работает месяцами без вмешательства, требует внимания к деталям. Правильный провайдер, обработка ошибок, задержки, мониторинг, резервный пул.

Начни с backconnect-прокси от нормального провайдера. Напиши простой ротатор с бан-листом. Добавь рандомные задержки. Настрой алерты. Потом итерируй. Через пару недель у тебя будет система, которая просто работает. И ты наконец перестанешь просыпаться от алертов в три часа ночи.

Ну, почти перестанешь.

Последние материалы