Реализация прокси-ротации для парсинга
При промышленном парсинге один IP-адрес быстро блокируется: сайты фиксируют высокую частоту запросов и выдают 403 или 429. Потери данных при этом достигают 40%. Ручная смена прокси неэффективна — нужно автоматическое решение. Мы строим систему, которая распределяет запросы по пулу адресов, выводит заблокированные на карантин и взвешенно выбирает самые надёжные прокси. Опыт показывает: грамотная ротация повышает сбор данных до 99,5%.
Как работает взвешенный выбор прокси?
Каждый прокси в пуле хранит статистику успешных и неудачных запросов. Ротатор вычисляет success_rate как отношение успешных запросов к общему числу. При выборе адреса используется взвешенная случайность: прокси с коэффициентом 0.92 выбирается в 7 раз чаще, чем с 0.5. Если прокси возвращает ошибку (403, 429, таймаут), он помещается на карантин на 15 минут (настраивается). Это предотвращает повторные попытки через заведомо заблокированный IP.
Request → Proxy Selector ↓ [Proxy Pool] 192.168.1.1:8080 ← статус: OK, 245 запросов, скор 0.92 10.0.0.5:3128 ← статус: OK, 198 запросов, скор 0.88 172.16.0.2:8080 ← статус: BLOCKED, на карантине ↓ Target Site ↓ Response Checker (статус 200 → success / 403/429 → fail) Как интегрировать ротатор с aiohttp?
Интеграция строится на asyncio и aiohttp. Функция fetch получает прокси из ротатора, выполняет запрос и отчитывается об успехе. При ошибке прокси уходит на карантин, и следующий запрос получит другой адрес. Это позволяет обрабатывать до 1000 запросов в минуту без блокировок.
import asyncio import aiohttp from dataclasses import dataclass, field from datetime import datetime, timedelta @dataclass class ProxyEntry: url: str success: int = 0 fail: int = 0 blocked_until: datetime = field(default_factory=lambda: datetime.min) @property def is_available(self): return datetime.now() > self.blocked_until @property def success_rate(self): total = self.success + self.fail return self.success / total if total > 0 else 0.5 class ProxyRotator: def __init__(self, proxies: list[str], quarantine_minutes=15): self.pool = [ProxyEntry(url=p) for p in proxies] self.quarantine = timedelta(minutes=quarantine_minutes) self._lock = asyncio.Lock() async def get(self) -> ProxyEntry: async with self._lock: available = [p for p in self.pool if p.is_available] if not available: raise RuntimeError("All proxies are blocked") weights = [p.success_rate for p in available] return random.choices(available, weights=weights)[0] async def report(self, proxy: ProxyEntry, success: bool): async with self._lock: if success: proxy.success += 1 else: proxy.fail += 1 proxy.blocked_until = datetime.now() + self.quarantine async def fetch(session, url, rotator): proxy = await rotator.get() try: async with session.get(url, proxy=proxy.url, timeout=10) as resp: if resp.status in (403, 429, 503): await rotator.report(proxy, success=False) return None await rotator.report(proxy, success=True) return await resp.text() except Exception: await rotator.report(proxy, success=False) return None Почему взвешенный выбор лучше случайного?
Случайный выбор прокси перегружает систему ошибками: плохие адреса получают столько же запросов, сколько хорошие. Взвешенный подход, основанный на success_rate, аналогичен методу экспоненциального сглаживания — чем дольше прокси работает стабильно, тем чаще он используется. Это снижает число повторных запросов на 30% и ускоряет сбор данных. Дополнительно мы внедряем мониторинг прокси: каждые 5 минут проверяем доступность пула и автоматически исключаем долго заблокированные адреса.
Сравнение пулов: резидентные vs ISP vs дата-центр
| Тип прокси | Скорость | Анонимность | Стоимость | Устойчивость к блокировкам |
|---|---|---|---|---|
| Резидентные | Низкая | Высокая | Высокая | Очень высокая |
| ISP | Средняя | Средняя | Средняя | Высокая |
| Дата-центр | Высокая | Низкая | Низкая | Низкая |
Резидентные прокси (например, от Bright Data) дают наилучший обход блокировок, но дороже — экономия бюджета достигается за счёт меньшего числа повторных запросов. ISP-прокси (Oxylabs) — золотая середина для парсинга интернет-магазинов. Дата-центр подходит только для быстрых прототипов, где допустимы временные блоки.
Что делать, если все прокси в карантине?
Алгоритм проверяет blocked_until для каждого адреса. Если все недоступны, выбрасывается исключение — это сигнал для оператора. На практике мы рекомендуем резервный пул из 5–10 прокси с увеличенным временем ожидания между запросами. При пуле из 20 резидентных прокси с настройками по умолчанию парсер работает без простоев в 99% случаев. В сложных сценариях автоматически увеличиваем quarantine_minutes до 30, чтобы снизить нагрузку на пул.
Этапы внедрения системы ротации
- Анализ целевых сайтов: определение таргетинга, лимитов запросов, типов блокировок.
- Выбор прокси-провайдера: подбор оптимального пула (резидентные/ISP/микс) под бюджет и задачи.
- Разработка ротатора: реализация взвешенного выбора, карантина и мониторинга.
- Интеграция с парсером: подключение
aiohttp, обработка ошибок, логирование. - Нагрузочное тестирование: прогон 10 000 запросов, проверка стабильности при пиковых нагрузках.
Выбор прокси-провайдера: сравнение по целевым задачам
| Задача | Рекомендуемый провайдер | Минимальный пул |
|---|---|---|
| Парсинг интернет-магазинов (RU) | Oxylabs ISP | 10 IP |
| Сбор данных с соцсетей | Bright Data Resident | 20 IP |
| Быстрое прототипирование | Smartproxy Datacenter | 5 IP |
Для большинства задач достаточно 10–15 резидентных прокси от Smartproxy при адекватных задержках. Если требуется глобальное покрытие, выбирайте Bright Data — их пул включает 72 млн IP.
Что входит в результат
- Архитектура системы ротации с документацией
- Исходный код на Python с asyncio и интеграцией с aiohttp
- Инструкция по развёртыванию (Docker, настройка мониторинга)
- Двухнедельная поддержка после внедрения
Мы занимаемся разработкой систем парсинга более 5 лет, реализовали 15+ проектов с прокси-ротацией. Все решения проходят нагрузочное тестирование. Получите консультацию — пришлём оценку за 1 день. Закажите реализацию — внедрим систему за 2–3 дня.
Сроки
Базовая система — 2–3 рабочих дня. Под ключ с адаптацией под ваш стек — до 5 дней.







