Як уникати капчі під час скрапінгу (без порушення правил)
Більшість капч під час скрапінгу — це реакція на трафік, який виглядає автоматизованим. Найдешевший спосіб з ними впоратися — перестати їх провокувати. Для цього спершу шукайте легітимне джерело даних, перевіряйте, що дозволяють правила сайту, надсилайте менше запитів і повільніше, та не завантажуйте одну сторінку двічі. Розв'язання капчі — запасний варіант для випадків, яких не вдається уникнути, а не основний план.
Спершу перевірте наявність офіційного API або стрічки
Багато сайтів, які скрапають, уже пропонують спосіб отримати ті самі дані без капчі: публічний API, експорт даних, RSS- або sitemap-стрічку чи партнерську програму. Офіційне джерело надійніше, рідше змінюється без попередження і дає власнику сайту контроль над тим, як ним користуються. Шукайте:
- розділ для розробників або API внизу сторінки;
sitemap.xmlзі списком сторінок;- посилання RSS або Atom у
<head>сторінки; - сторінку «data» або «download» для масових експортів.
Якщо один із цих варіантів покриває вашу потребу, користуйтеся ним. Ви уникнете більшості капч, просто не запитуючи HTML.
Дотримуйтесь robots.txt і затримки, яку він просить
robots.txt показує, які шляхи дозволено завантажувати автоматизованим клієнтам і, інколи, скільки чекати між запитами. Стандартна бібліотека Python може прочитати його за вас:
import time
from urllib.robotparser import RobotFileParser
import requests
USER_AGENT = "ExampleBot/1.0 (+https://example.com/bot)"
parser = RobotFileParser()
parser.set_url("https://example.com/robots.txt")
parser.read()
delay = parser.crawl_delay(USER_AGENT) or 5 # запасний варіант: обережні 5 секунд
urls = [
"https://example.com/products?page=1",
"https://example.com/products?page=2",
]
last_request = 0.0
for url in urls:
if not parser.can_fetch(USER_AGENT, url):
print("skipped by robots.txt:", url)
continue
wait = delay - (time.monotonic() - last_request)
if wait > 0:
time.sleep(wait)
resp = requests.get(url, headers={"User-Agent": USER_AGENT}, timeout=30)
last_request = time.monotonic()
print(url, resp.status_code)
Якщо robots.txt забороняє шлях, чесна відповідь — не чіпати його або спитати власника. Обхід через браузер не змінює того, що просив сайт.
Сповільнюйте і розподіляйте запити
Стабільний, помірний темп рідко провокує виклик, а сплеск майже завжди провокує. Кілька звичок дають велику різницю:
- Оберіть один темп запитів для сайту і дотримуйтесь його, а не працюйте на повній швидкості.
- Додайте випадковий джитер, щоб час між запитами не був ідеально регулярним.
- Зупиніться і почекайте, коли бачите 429 або сторінку з капчею.
- Запускайте завдання в непікові години, якщо вас турбує навантаження на сайт.
Кешуйте і не завантажуйте повторно
Кожен запит, який ви не надсилаєте, — це запит, який сайт не мусить обробляти. Зберігайте сторінки, які завантажили, з датою і хешем вмісту, і завантажуйте їх знову лише тоді, коли вміст, імовірно, змінився. Умовні запити з заголовками If-Modified-Since або ETag дозволяють серверу дешево відповісти «не змінилося», якщо він це підтримує.
Повторно використовуйте сесії і надсилайте звичайні заголовки
Сесія, яка зберігає cookie між запитами, поводиться більше як відвідувач, ніж скрипт, що стартує з нуля щоразу. Використовуйте requests.Session() для кожного сайту і надсилайте чесний, зрозумілий User-Agent з назвою вашого бота та контактом. Не маскуйтеся під браузер, щоб обійти правило. Якщо сайту для показу вмісту потрібен JavaScript, використовуйте інструмент браузера для таких сторінок і дотримуйтесь тих самих лімітів частоти.
Коли капча все одно з'являється
Деякі сайти показуватимуть капчу, незалежно від того, наскільки обережно ви поводитеся. Визначте її в коді і зупиніть це завдання, а не долбіть сторінку. Виявлення і необов'язкове розв'язання для PopularCaptcha описані в посібнику про капчу при веб-скрапінгу.
Сплануйте обхід до початку
Обхід, який щодня завантажує все, — найпростіший спосіб спровокувати капчу. Спершу сплануйте роботу:
- Розставте пріоритети. Визначте, які сторінки змінюються часто, а які рідко. Часті скрапайте часто, решту — рідко.
- Використовуйте дати з sitemap. Багато sitemap-файлів містять значення
lastmod. Пропускайте URL, які не змінилися з вашого останнього візиту. - Скрапайте інкрементально. Зберігайте останнє успішне завантаження для кожного URL і після збою продовжуйте з цього місця, а не починайте з першої сторінки.
- Розподіляйте навантаження. Поділіть великий список на пакети і запускайте їх протягом дня, а не всі одразу.
Такий план зменшує кількість запитів, а це найбільший важіль, який у вас є.
Запишіть план у короткий конфігураційний файл або таблицю: сайти, розділи, інтервал оновлення і денний бюджет запитів для кожного. Коли бюджет вичерпано, завдання зупиняється до наступного вікна. Сприймати бюджет як жорсткий ліміт, а не орієнтир, — це те, що не дає скраперу зсунутися до патерну трафіку, який і провокує капчу. Переглядайте бюджет кожні кілька тижнів, бо сайт, що зростає, може також збільшити трафік, і те, що було ввічливим минулого кварталу, зараз може таким не бути.
Scrape responsibly
- Перевірте
robots.txtі умови використання, перш ніж почати, і дотримуйтесь того, що там сказано. - Тримайте низьку частоту запитів і зупиняйтеся, коли сайт дає знати, що йому складно.
- Не збирайте персональних даних, які вам не потрібні, і видаляйте їх, коли вони більше не потрібні.
- Не публікуйте масово захищений авторським правом вміст. Використовуйте дані для аналізу, порівняння чи власного продукту, і вказуйте джерело там, де це доречно.
- Зверніться до власника сайту, якщо вам потрібен більший обсяг. Можливо, він запропонує стрічку.