Scarnox · Blog

Как не получить блок при парсинге: практическое руководство с кодом

Блокировка при парсинге обычно означает одно из трех: вы отправили слишком много запросов слишком быстро, ваш клиент выглядел не как браузер или известный бот, либо ваш IP-адрес находится в списке, которому сайт меньше доверяет. Все три можно уменьшить несколькими привычками: замечать блок рано, замедляться, когда сайт сопротивляется, вести последовательную и честную идентичность и использовать прокси только там, где это уместно. Это руководство разбирает каждый пункт с рабочим кодом. Используйте его для сайтов, парсинг которых вам разрешен.

Распознавайте блок

Блок не всегда выглядит как страница ошибки. Следите за:

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

Отступайте с повторами

Когда сайт говорит «помедленнее», ваш код должен замедлиться заметно. Экспоненциальная пауза с ограничением числа попыток — стандартный подход. Она также учитывает Retry-After, если сайт его присылает:

import time
import requests

session = requests.Session()
session.headers.update({
    "User-Agent": "ExampleBot/1.0 (+https://example.com/bot)",
    "Accept-Language": "en-US,en;q=0.9",
})

def polite_get(url: str, max_attempts: int = 4) -> requests.Response:
    delay = 2.0
    resp = None
    for _ in range(max_attempts):
        resp = session.get(url, timeout=30)
        if resp.status_code not in (429, 503):
            return resp
        retry_after = resp.headers.get("Retry-After", "")
        wait = float(retry_after) if retry_after.isdigit() else delay
        time.sleep(wait)
        delay *= 2
    return resp  # все еще заблокирован: вернуть последний ответ, чтобы вызывающий код его обработал

resp = polite_get("https://example.com/products?page=1")
print(resp.status_code, len(resp.text))

Обратите внимание, чего функция не делает. Она не повторяет 403 и не переключает личности, чтобы обойти один блок. 403 — это решение остановиться, а не головоломка, которую нужно решить.

Диагностируйте блок по шагам

Когда запуск начинает падать, пройдите эти проверки, прежде чем что-то менять:

  1. Посмотрите на первый упавший URL и его код статуса. Блок обычно начинается в определенной точке, а не случайно.
  2. Сравните частоту запросов за минуты до первой ошибки. Всплеск — самая частая причина.
  3. Проверьте, привязана ли ошибка к одному пути, одному разделу или времени суток.
  4. Откройте тот же URL один раз вручную в обычном браузере. Если браузер загружает страницу, разница в вашем паттерне запросов. Если браузер тоже заблокирован, сайт на данный момент перестал отдавать вам страницу.
  5. Только потом меняйте код. Сначала замедлитесь, второе — добавьте отступы, и в последнюю очередь пересмотрите идентичность.

Если менять несколько вещей сразу, невозможно понять, что помогло.

Сохраняйте последовательную и честную идентичность

Парсеры блокируют, когда их идентичность меняется от запроса к запросу или не совпадает с остальным трафиком. Одна сессия с одним понятным User-Agent — самая простая стабильная идентичность. Назовите своего бота, добавьте контактную ссылку и отправляйте только те заголовки, которые отправил бы обычный клиент. Смена User-Agent, чтобы выглядеть как множество разных посетителей, — форма обхода, и она скорее усиливает блокировку, чем ослабляет ее.

Если сайт отдает браузерам другой контент, чем простым HTTP-клиентам, используйте настоящий браузер для этих страниц и держите ту же границу частоты. Это законный путь, и он сохраняет разумный паттерн запросов.

Используйте прокси осторожно

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

proxies = {
    "http": "http://user:pass@proxy.example.net:8000",
    "https": "http://user:pass@proxy.example.net:8000",
}
resp = session.get("https://example.com/products", proxies=proxies, timeout=30)

Выбор типа прокси — отдельный вопрос, он разобран в резидентских и датацентровых прокси и ротации прокси для парсинга.

Когда блок превращается в капчу

Некоторые сайты отвечают на проблему частоты капчей, а не жесткой блокировкой. Разумный порядок: остановиться, замедлиться, снова проверить правила и только потом рассматривать решение капчи. Для виджетов PopularCaptcha живой API Scarnox возвращает токен, который вы отправляете в поле h-captcha-response. Для других типов капчи проверяйте актуальный список, потому что поддержка reCAPTCHA, Cloudflare Turnstile, GeeTest, AWS WAF и Arkose скоро появится. Подробное руководство — парсинг капчи в вебе.

Если вы начали видеть блоки на сайте, причина почти всегда в паттерне запросов. Избегание капчи при парсинге описывает привычки, которые этому препятствуют.

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

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