Ты запускаешь парсер. Первые 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
Тут развилка, и она принципиальная.
- Список IP — это когда провайдер даёт тебе файл с 500 или 1000 адресами. Ты сам управляешь ротацией. Плюс — полный контроль. Минус — IP «горят», и тебе нужно самому отслеживать, какие ещё живые.
- 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-прокси от нормального провайдера. Напиши простой ротатор с бан-листом. Добавь рандомные задержки. Настрой алерты. Потом итерируй. Через пару недель у тебя будет система, которая просто работает. И ты наконец перестанешь просыпаться от алертов в три часа ночи.
Ну, почти перестанешь.
