top of page

Сколько прокси для парсинга нужно на 100 000 страниц

06.10.26

Две формулы на пул и потоки и готовые настройки для requests, httpx и A-Parser

WinGate: приватные прокси IPv4 и SOCKS5, бесплатный тест до 2 часов
Прокси для парсинга: формулы числа потоков и размера пула адресов

Считать прокси для парсинга нужно от двух чисел: сколько страниц в час вам нужно и сколько запросов сайт спокойно принимает с одного адреса. Первое число даёт потоки. Второе даёт размер пула. Ротация, паузы и повторы нужны, чтобы эти расчёты не развалились на первом же 429.


Я выучил это на каталоге в 180 000 карточек, когда запустил 60 потоков через десять адресов и уже на 12-й минуте получил вместо карточек сплошную стену из ответов 429. После пересчёта тот же каталог шёл в 16 потоков через пул с ротацией и прошёл за ночь с долей 429 меньше процента.


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


Сколько потоков нужно: считаем от скорости

Формула простая, это закон Литтла из теории очередей. Потоки равны нужной скорости в запросах в секунду, умноженной на время одного цикла, где цикл складывается из ответа сайта и паузы перед следующим запросом, которую вы ставите сами.


Пример. 100 000 страниц за 8 часов дают 100 000 ÷ 28 800 секунд, то есть 3,47 запроса в секунду. Средний ответ через прокси пусть занимает 1,6 секунды, случайная пауза от 1 до 3 секунд даёт в среднем 2. Цикл выходит 3,6 секунды, и 3,47 × 3,6 даёт 12,5. Округляем до 13. Добавляем четверть на повторы. Получается 16 потоков. Не 60.


Больше ставить смысла нет. Если сайт уже отвечает на пределе своего лимита, лишние потоки превращаются в лишние 429, и общая скорость прогона падает.


Сколько адресов: считаем от лимита на IP

Вторая формула: число адресов равно запросам в минуту, делённым на безопасный темп одного IP. 3,47 запроса в секунду дают 208 в минуту. Темп меряют лесенкой. Берёте один адрес, шлёте 2 запроса в минуту в течение 5 минут, потом 4, потом 6 и дальше с шагом 2, пока не прилетит первый 429 или капча. Рабочим темпом берёте половину от этой точки.


На том каталоге первый 429 приходил на 12 запросах в минуту с адреса. Половина даёт 6. 208 ÷ 6 = 34,7, значит минимум 35 адресов, и каждый из них должен получать не больше 6 запросов в минуту. Годность адресов перед прогоном удобно проверить многопоточным скриптом на curl или Python.


Лимит бывает привязан не только к IP. Сайты считают запросы на куки, на сессию, на раздел. Поиск и фильтры почти везде ограничены жёстче карточек товара, поэтому лесенку стоит прогнать на том типе страниц, который вы реально собираете, и записать результат рядом с настройками задания.


Расчёт по шагам: 100 000 страниц за 8 часов, 16 потоков и 35 адресов

429 и 403: два разных сигнала

В логах парсера «ошибкой парсинга» называют любой ответ, из которого не удалось достать данные: 429, 403, капчу, обрезанную страницу. Запрос «ошибка парсинга что это» задают и владельцы Android, у них так называют сбой при установке приложения, и к сбору данных он отношения не имеет. Нас интересуют коды. Реакция на них разная.


Код 429 Too Many Requests говорит о темпе. Сайт посчитал запросы и упёрся в свой лимит. Часто к ответу приложен заголовок Retry-After: число секунд или дата, до которой ждать. Ждите ровно столько. Мгновенный повтор выглядит как атака и продлевает блок. Без заголовка помогает экспоненциальная пауза со случайной добавкой: 2, 4, 8 секунд плюс немного случайности, чтобы потоки не просыпались одновременно.


Код 403 Forbidden говорит о доступе. Сайту не понравился адрес, отпечаток запроса или сам раздел закрыт для роботов. Сначала проверьте заголовки: библиотека requests по умолчанию представляется строкой python-requests с номером версии, и многие сайты режут её сразу. Потом новый IP через ротацию и темп пониже. Если 403 держится на десятках разных адресов подряд, сайт сознательно закрыл этот раздел. Остановитесь и поищите открытый источник или API.


Код 200 ещё не успех. Капча и заглушка часто приходят с кодом 200. Проверяйте в ответе элемент, ради которого пришли, цену или заголовок карточки, и считайте пустую страницу ошибкой. Ответ 404 повторять бессмысленно: страницы нет. 503 и таймауты повторяйте с паузой через новое соединение.


Для досок объявлений со своими лимитами есть отдельный разбор парсинга Авито через прокси.


Ротация: новый IP на запрос и ловушка keep-alive

Ротация на каждый запрос распределяет нагрузку по пулу сама: адрес меняется, и ни один IP не набирает лишнего. Тут есть подвох. Внутри одного HTTPS-туннеля прокси не видит отдельных запросов, поэтому новый выходной адрес выдаётся на новое соединение. Библиотеки же держат соединения открытыми ради скорости, и requests.Session или httpx.Client спокойно отправят сотню запросов подряд через один туннель и один IP.


Лечится заголовком Connection: close. Сайт закрывает соединение после ответа, библиотека открывает новое, и каждый запрос уходит с нового адреса. Для каталогов, выдачи и карточек это то, что нужно: каждая страница открывается по своей ссылке и не зависит от предыдущей.


Куки при ротации лучше не копить. Сессия, которая каждые пару секунд приходит с нового адреса, выглядит странно. Для открытых карточек куки и не нужны: в requests.Session их сбрасывает вызов s.cookies.clear() после каждого ответа.


Как парсер реагирует на ответы 200, 429, 403, 404, 503 и таймаут

Прокси для парсинга в Python: requests и httpx

С requests повторы удобнее всего отдать адаптеру с классом Retry из urllib3: он сам повторит запрос на 429 и 5xx, увеличивая паузу вдвое с каждой попыткой, и по умолчанию честно выдержит Retry-After на кодах 429 и 503:


import random, time
import requests
from requests.adapters import HTTPAdapter
from urllib3.util import Retry

PROXY = "http://ЛОГИН:ПАРОЛЬ@IP:ПОРТ"
retry = Retry(total=5, backoff_factor=2, status_forcelist=[429, 500, 502, 503, 504])

s = requests.Session()
s.mount("http://", HTTPAdapter(max_retries=retry))
s.mount("https://", HTTPAdapter(max_retries=retry))
s.headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
                  "Connection": "close"})

for url in urls:
    try:
        r = s.get(url, proxies={"http": PROXY, "https": PROXY}, timeout=(5, 30))
        if r.status_code == 200:
            save(url, r.text)
    except requests.RequestException as e:
        print(url, type(e).__name__)
    time.sleep(random.uniform(1, 3))

Прокси передаётся в каждый вызов намеренно: значение в session.proxies могут перебить переменные окружения. Для нескольких потоков заверните цикл в ThreadPoolExecutor и заведите по сессии на поток. Готовые варианты лежат на странице про прокси для python.


Асинхронный httpx держит те же 16 потоков семафором. Параметр proxy появился в версии 0.26, старый proxies убран в 0.28:


import asyncio, random
import httpx

PROXY = "http://ЛОГИН:ПАРОЛЬ@IP:ПОРТ"
HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Connection": "close"}

async def fetch(client, sem, url):
    async with sem:
        for attempt in range(5):
            try:
                r = await client.get(url)
            except httpx.TransportError:
                await asyncio.sleep(2 ** attempt)
                continue
            if r.status_code in (429, 503):
                ra = r.headers.get("Retry-After", "")
                await asyncio.sleep(int(ra) if ra.isdigit() else 2 ** attempt + random.random())
                continue
            await asyncio.sleep(random.uniform(1, 3))
            return url, r.status_code, r.text
        return url, "fail", ""

async def main(urls):
    sem = asyncio.Semaphore(16)  # потоки из расчёта
    async with httpx.AsyncClient(proxy=PROXY, headers=HEADERS, timeout=30) as client:
        return await asyncio.gather(*(fetch(client, sem, u) for u in urls))

results = asyncio.run(main(urls))

Для SOCKS5 поставьте pip install "httpx[socks]" и схему socks5h. Сотни тысяч ссылок режьте на порции по несколько тысяч, иначе gather создаст все задачи в памяти разом.


Прокси в A-Parser: четыре настройки

  1. Меню «Проксичекер», кнопка «Добавить чекер». Список кладётся в файл files/proxy/<имя чекера>/proxy.txt в формате login:password@ip:port. Второй вариант: строки ip:port и галочка «Использовать авторизацию прокси» с логином и паролем в настройках чекера.

  2. Для пула с ротацией включите No check proxies. Все загруженные прокси считаются живыми, и чекер не тратит потоки на их регулярную перепроверку.

  3. Настройки, затем «Настройки потоков». Число потоков берёте из расчёта. Максимум подключений на один хост ограничивает одновременные запросы к сайту, документация прямо называет его способом снизить нагрузку. Повторное использование прокси между попытками документация советует включать, когда за одним прокси выходной IP меняется при каждом подключении.

  4. В настройках парсера: Request delay задаёт паузу между запросами, Request retries число попыток (по умолчанию 10), Proxy ban time время, на которое адрес убирают из оборота.


Учтите, что A-Parser складывает потоки всех заданий и проверок проксичекера в один общий счёт.


Первый запуск делайте коротким. 2000 ссылок, 16 потоков, лог кодов ответа. Если доля 429 выше пары процентов, поднимайте Request delay на секунду или убавляйте потоки, если ниже, можно осторожно добавить пару потоков и посмотреть ещё раз. Подбор занимает три или четыре коротких прогона по 10 минут и окупается на всём объёме, потому что ошибка в темпе на сотне тысяч страниц стоит часов повторной работы. Перевести список из формата с двоеточиями в формат с @ можно одной командой из статьи о форматах подключения прокси. Подробности на странице прокси для a-parser.


Где взять 35 адресов, которые не придётся менять руками

Расчёт выше упирается в пул. Десятки адресов, у каждого лимит, и каждый со временем начинает ловить 403, после чего его надо найти, выкинуть и заменить, не останавливая прогон.


Пул с ротацией делает это за вас: один вход, новый IP на каждый запрос, и нагрузка размазывается сама. У WinGate прокси для парсинга работают по HTTP, HTTPS и SOCKS5, на приватных IPv4, с безлимитным трафиком, что важно при тяжёлых страницах, и до 5000 потоков. Авторизация по IP или строкой IP:PORT:LOGIN:PASS, которую A-Parser и скрипты принимают после одной замены.


Расчёт стоит сверить с живым сайтом. Запустите прогон на 16 потоках с паузами из этой статьи через тестовый доступ и посчитайте долю ответов 429 за первый час: тест бесплатный, до 2 часов.

WinGate: приватные прокси IPv4 и SOCKS5, бесплатный тест до 2 часов

Свежие статьи

14.10.26

Прокси не работает: 9 причин и как найти свою за 5 минут

Сначала тест за 60 секунд. Потом симптомы, коды и 9 причин по порядку.

13.10.26

Подключение прокси и символ @, который ломает всю строку

Где задаётся подключение, как записать строку и какую авторизацию выбрать

12.10.26

Как проверить прокси командой curl

От «жив ли адрес» до прогона списка из 500 строк за пару минут

О справочнике

Proxyra разбирает прокси по делу: настройка в Windows, Linux и браузерах, коды ошибок, прокси в парсерах и антидетектах. Команды из статей можно копировать и запускать сразу.

© 2026 Proxyra. Справочник по настройке и ошибкам прокси.

bottom of page