Ротаційні проксі для скрапінгу: налаштування і пастки
Ротаційний проксі змінює IP-адресу, з якої виходить ваш трафік, або на кожному запиті, або після заданого інтервалу. Це один з найпоширеніших інструментів у веб-скрапінгу і один з найчастіше використовуваних неправильно. Ротуєте замало - одна адреса отримує обмеження частоти. Ротуєте занадто часто - трафік зовсім не схожий на відвідувача. Цей посібник пояснює дві моделі ротації, показує робочу конфігурацію на Python з повторами для мертвих проксі і розповідає, як поле проксі вписується в розв'язання капчі.
Ротація проти закріплених сесій
Сервіс ротаційних проксі видає адреси двома способами:
- Ротація на кожен запит. Кожен запит отримує нову вихідну адресу. Це підходить для великих обходів багатьох непов'язаних сторінок, де жодна сторінка не потребує попередньої.
- Закріплені сесії. Одна адреса зберігається протягом заданого часу, часто кількох хвилин, або доки ви її не звільните. Це підходить для всього, що потребує стану: логіну, кошика покупок, пагінованого списку, де важливі cookie.
Справжній відвідувач зберігає одну адресу протягом усього візиту. Закріплені сесії повторюють цю поведінку, тож вони зазвичай кращий вибір за замовчуванням, коли сайт використовує cookie або сесії. Ротацію на кожен запит використовуйте для безстанового обходу.
Базовий ротаційний пул на Python
Приклад нижче тримає пул URL проксі, перемикається між ними і переходить до наступного, коли один не працює. Зберігайте облікові дані у змінних середовища, ніколи в коді.
import itertools
import os
import requests
# URL проксі беруться зі змінних середовища, наприклад:
# PROXY_POOL="http://user:pass@203.0.113.10:8080,http://user:pass@203.0.113.11:8080"
PROXIES = [p.strip() for p in os.environ.get("PROXY_POOL", "").split(",") if p.strip()]
rotation = itertools.cycle(PROXIES)
def fetch(url: str, max_tries: int = 3) -> requests.Response:
last_error = None
for _ in range(max_tries):
proxy = next(rotation)
try:
r = requests.get(
url,
proxies={"http": proxy, "https": proxy},
timeout=30,
)
if r.status_code == 407: # проксі відхилило автентифікацію
raise requests.RequestException("proxy auth rejected")
return r
except requests.RequestException as exc:
last_error = exc # мертвий або повільний проксі: спробувати наступний
raise RuntimeError(f"all attempts failed for {url}: {last_error}")
Два моменти тут важливі. По-перше, мертвий проксі треба повторювати на іншій адресі, а не на тій самій. По-друге, запит, що завершився помилкою автентифікації, має зупинитися і бути зафіксованим, а не витрачати весь пул.
Відстежуйте здоров'я проксі
Просте циклічне розподілення продовжує слати трафік на проксі, який почав відмовляти. Ведіть простий показник для кожної адреси: рахуйте останні невдачі і виключайте адресу з пулу на період охолодження, коли вона перевищує поріг. Поверніть її пізніше і знову стежте. Тоді скрапер витрачає запити на здорову частину пулу.
Записуйте проксі, що використовувався для кожного результату. Коли сайт починає повертати блокування, вам знадобиться знати, чи винна одна адреса, один регіон чи весь пул.
Регулюйте темп пулу
Ротація розподіляє навантаження між адресами, але в кожної адреси все ще є свій ліміт. Встановіть затримку для кожної адреси і глобальне обмеження на кількість запитів за секунду по всьому пулу. Ротація - це не ліцензія на більший трафік. Це спосіб тримати трафік однієї адреси в розумних межах.
Типові помилки
Більшість проблем з ротацією походить від кількох звичок. Зміна адреси посеред логіну або оформлення замовлення ламає сесію і робить сайт підозрілим. Відповідь 429 - це обмеження частоти на боці сайту, а не зламаний проксі, тож перемикання на нову адресу та негайний повтор лише поширюють проблему. Зміна адреси на кожному запиті з тими самими cookie теж непослідовна, бо cookie були видані іншому відвідувачу. Нарешті, пул, який ніколи не перевіряють, тихо заповниться мертвими адресами, і частота помилок зросте без очевидної причини. Перевіряйте пул за розкладом і видаляйте те, що не працює.
Проксі і розв'язання капчі
Деякі завдання з капчею можуть використовувати той самий проксі, що й ваш скрапер. Ви передаєте його в необов'язковому полі proxy у форматі http://user:pass@host:port, і розв'язання відбувається по тому ж мережевому шляху, що й запит сторінки. Завдання без проксі пропускають це поле повністю. Який варіант обрати, залежить від того, чи прив'язує сайт капчу до мережевої адреси. Цей компроміс пояснено в розв'язання капчі через проксі і без проксі.
Два практичні моменти:
- Використовуйте той самий проксі для запиту сторінки і для розв'язання, якщо сайт перевіряє адресу. Змішування адрес може призвести до невдачі токена.
- Токени спливають швидко. Запитуйте токен прямо перед відправкою форми, а не задовго до неї. Див. термін дії токена капчі.
Жива капча в Scarnox сьогодні - це PopularCaptcha. Посібник по PopularCaptcha для Python показує запит і те, як відправити отриманий токен.
Вибір проксі
Тип адрес, які ви ротуєте, має таке ж значення, як і сама ротація. Адреси дата-центрів швидкі і дешеві на запит, але часто мають низьку оцінку. Резидентні адреси мають кращу оцінку і повільніші. Резидентні та дата-центрові проксі детально порівнює їх, і порада звідти стосується пулу, який ви будуєте тут.
Скрапінг відповідально
- Читайте
robots.txtі умови сайтів, які скрапите. - Використовуйте проксі, щоб розподіляти легітимне навантаження, а не щоб обходити обмеження, встановлене власником сайту.
- Використовуйте лише сервіси проксі, чиї адреси отримані за згодою. Маршрутизація через пристрої людей, які не погодилися на це, є неприйнятною.
- Тримайте облікові дані поза кодом і логами.
Що далі
- Резидентні та дата-центрові проксі
- Скрапінг без блокувань
- Проксі чи без проксі для капчі
- Повтори і обробка помилок, які витримують продакшен
Почніть з безкоштовного пробного кредиту, картка не потрібна: створіть обліковий запис і протестуйте потік PopularCaptcha зі своїм проксі. Актуальні тарифи дивіться на сторінці тарифів.