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 скоро з'явиться. Детальний посібник - скрапінг з капчею.

Якщо ви починаєте бачити блокування на сайті, причина майже завжди в шаблоні запитів. Уникнення капчі під час скрапінгу описує звички, які цьому запобігають.

Скрапінг відповідально

Що далі