Веб-скрапинг Airbnb: как обойти антибот-систему Kasada и не словить блок
Содержание
- Почему обычные библиотеки умирают мгновенно
- Что внутри Kasada
- Схема обхода: браузерный движок + ротация
- Убираем следы автоматизации
- Ротация IP: почему резиденты решают
- Реальные кейсы обхода
- Анти-детект плагины: помощь или иллюзия
- API-эндпоинты Airbnb
- Ограничения скорости и тайминги
- Что делать, если бан прилетел
- Легальные альтернативы
- Итоги
Airbnb — один из самых защищённых сайтов для скрапинга. Не Cloudflare, не PerimeterX, а именно Kasada. Система, которая заточена под перехват автоматизированных запросов на уровне TLS-отпечатков, поведения мыши и даже таймингов ввода.
Попытка дёрнуть API без подготовки заканчивается одинаково: HTTP 403, пустое тело ответа и тишина в логах. Разберём, как это работает и что реально помогает.
Почему обычные библиотеки умирают мгновенно
Requests, httpx, curl — все они оставляют характерный след. Kasada смотрит не на заголовки, а на TLS ClientHello — структуру приветствия, порядок расширений, список cipher suites. У стандартного openssl из Python этот отпечаток один, у Chrome — другой. Разница видна сразу.
Пример: обычный запрос через requests даёт JA3-отпечаток `771,4865-4866-4867-49195-49199...`. Chrome даёт `771,4865-4866-4867-49195-49199-49196-49200...` — отличается порядком и набором. Kasada сверяет это за миллисекунды.
Второй уровень — поведенческий. Система анализирует движение мыши, скорость скролла, интервалы между кликами. Для скрапера это смертный приговор: без реального браузера или эмуляции поведения вычислить вас тривиально.
Что внутри Kasada
Kasada — это не один скрипт, а связка:
- **TLS-отпечатки** — проверка на уровне рукопожатия
- **JS-инъекции** — обфусцированный код, который выполняется в браузере
- **Поведенческая аналитика** — mouse movement, keyboard timing
- **Honeypot-ловушки** — скрытые поля и элементы, которые видит только бот
- **Rate limiting** — адаптивный, с учётом вашего IP и отпечатка
Причём система обучается. Если вы один раз попали под подозрение, ваш отпечаток заносится в базу, и последующие запросы с тем же профилем режутся даже при смене IP.
Схема обхода: браузерный движок + ротация
Единственный рабочий путь — использовать настоящий браузерный движок (Chromium, Firefox) с автоматизацией, которая не палится. Простой Selenium с chromedriver умирает: Kasada определяет WebDriver по флагам.
Рабочая связка:
- **Playwright** или **Puppeteer** с патчами для скрытия автоматизации
- **Ротация User-Agent** и TLS-отпечатков
- **Резидентные прокси** с низкой репутацией
Пример на Python с Playwright:
```python
from playwright.sync_api import sync_playwright
import random
UA_LIST = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
]
with sync_playwright() as p:
browser = p.chromium.launch(
headless=False,
args=[
"--disable-blink-features=AutomationControlled",
"--disable-dev-shm-usage"
]
)
context = browser.new_context(
user_agent=random.choice(UA_LIST),
viewport={"width": 1920, "height": 1080},
locale="en-US"
)
Убираем следы автоматизации
context.add_init_script("""
Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
window.chrome = {runtime: {}};
""")
page = context.new_page()
page.goto("https://www.airbnb.com", wait_until="networkidle")
page.wait_for_timeout(5000)
page.screenshot(path="airbnb.png")
browser.close()
```
Ключевой момент — `--disable-blink-features=AutomationControlled`. Без него Playwright палится по флагу `navigator.webdriver`. Но даже с этим флагом Kasada может вычислить вас по эмуляции мыши.
Ротация IP: почему резиденты решают
Датацентровые прокси умирают почти сразу. Kasada сверяет IP с базами ASN, и если видит DigitalOcean, Hetzner или AWS — шанс на успех падает до нуля. Нужны резидентные прокси или мобильные.
Пример: скрапинг поисковой выдачи Airbnb с резидентными прокси давал задержку 2-4 секунды на запрос, но стабильность — 95% успешных ответов. С датацентровыми — 15% успеха и мгновенный бан.
Настройка прокси в Playwright:
```python
context = browser.new_context(
proxy={
"server": "http://residential-proxy.example.com:8080",
"username": "user",
"password": "pass"
}
)
```
Реальные кейсы обхода
**Кейс: сбор цен на жильё в Берлине**
Проблема: стандартный requests умирал на первом запросе. Причина — TLS-отпечаток Python, который Kasada определяет за 200 мс.
Решение: связка Playwright + резидентные прокси. Сбор 500 объявлений занимал 40 минут. Задержка между запросами — 7-12 секунд, случайная. Ни одного бана за 3 дня.
**Кейс: обход JS-инъекций**
Проблема: Kasada внедряет JS-код, который создаёт cookie `_aaxsc`. Без этого cookie API возвращает 403.
Решение: сначала открываем главную страницу, ждём 3-5 секунд, пока выполнится JS, потом переходим к API. Cookie подхватывается автоматически. В Playwright это решается через `wait_until="networkidle"` и паузу перед запросом.
**Кейс: поведенческий анализ**
Проблема: даже с браузером и прокси Kasada блокировала после 10-15 запросов. Причина — слишком быстрые переходы между страницами без движения мыши.
Решение: добавили эмуляцию движения мыши через `page.mouse.move()` со случайными координатами и задержками 100-300 мс. Плюс скролл с переменной скоростью. Блокировки прекратились.
Анти-детект плагины: помощь или иллюзия
Есть готовые решения — `undetected-chromedriver`, `puppeteer-extra-plugin-stealth`. Они работают, но не идеально. Kasada обновляется чаще, чем выходят патчи.
`undetected-chromedriver` реально помогает против Cloudflare, но против Kasada — лишь отсрочка. Через 20-30 запросов система начинает видеть аномалии в поведении.
Лучше собирать свою конфигурацию: патчить WebDriver, подменять отпечатки, добавлять случайные задержки. Это дольше, но результат стабильнее.
API-эндпоинты Airbnb
Airbnb использует GraphQL API. Основные эндпоинты:
- `POST /api/v3/StaysSearch` — поиск жилья
- `POST /api/v3/StaysPdpSections` — страница объявления
- `GET /api/v2/StaysSearch` — старый формат (иногда работает)
Запросы требуют заголовок `X-Airbnb-API-Key` и `X-CSRF-TOKEN`. Токен берётся из cookie или из HTML-метаданных.
Пример запроса к API:
```bash
curl -X POST 'https://www.airbnb.com/api/v3/StaysSearch' \
-H 'Content-Type: application/json' \
-H 'X-Airbnb-API-Key: your_api_key' \
-H 'X-CSRF-TOKEN: your_csrf_token' \
--data '{
"operationName": "StaysSearch",
"variables": {
"location": "Berlin, Germany",
"checkIn": "2025-06-01",
"checkOut": "2025-06-10",
"adults": 2
}
}'
```
Но без cookie `_aaxsc` этот запрос вернёт 403. Поэтому сначала — браузерная сессия.
Ограничения скорости и тайминги
Kasada не просто банит — она может отдавать поддельные данные. Например, цены на 30% выше реальных, чтобы сбить с толку. Или пустые результаты поиска.
Идеальный тайминг:
- 1 запрос каждые 8-15 секунд
- Паузы случайные, не кратные
- Не более 200 запросов с одного IP за час
- Смена прокси каждые 50-100 запросов
Если видите подозрительно одинаковые ответы — это фильтр. Меняйте прокси и почистите cookie.
Что делать, если бан прилетел
Бан выражается в 403 с пустым телом или HTML-страницей с капчей. Капча Kasada — это не reCAPTCHA, а своя система с движущимися элементами. Решается только вручную или через сервисы распознавания.
После бана:
1. Смените прокси
2. Очистите все cookie и localStorage
3. Подождите 15-30 минут
4. Смените User-Agent
5. Начните с главной страницы, а не с API
Легальные альтернативы
Airbnb официально запрещает скрапинг. Есть партнёрские программы и API для хостов, но они не дают доступ к полной базе объявлений.
Если нужны данные для аналитики — лучше смотреть в сторону официального RSS или партнёрских фидов. Это медленнее, но без риска бана.
Итоги
Обход Kasada — это постоянная гонка. Система обучается, и то, что работало вчера, завтра может умереть. Ключевые компоненты:
- Браузерный движок с патчами
- Резидентные прокси
- Ротация отпечатков
- Реалистичное поведение
Без браузера — никак. Без резидентов — никак. Всё остальное — дело терпения и тестов.
Если хочется сэкономить время на подборе прокси и настройке — на lexic.ml есть готовые решения для IPv6-ротации, которые частично снимают проблему с баном по IP. Но отпечатки TLS всё равно придётся настраивать вручную.