Простая задача - отслеживать скидку на пару товаров, не заходя вручную каждый день, - превратилась в многодневный разбор полётов с антибот-системами трёх крупнейших российских маркетплейсов. Ozon, Wildberries и Яндекс.Маркет оказались тремя совершенно разными стенами, каждая из которых держит свой эшелон обороны.
Не что, а откуда: IP-адрес важнее заголовков
Первый и главный инсайт пришёл быстро: одинаковый HTTP-запрос с сервера в дата-центре даёт 403, а с домашнего интернета - открывает страницу без вопросов. Антибот смотрит не на содержимое запроса, а на происхождение. Адреса облачных хостингов и VPS идут в отказ мгновенно. Мобильные IP получают капчу. Резидентные - домашние провайдеры вроде Ростелекома - проходят как свои.
Логика у платформ железная: настоящий покупатель сидит дома, а не шлёт запросы из амазоновского облака. Выход - резидентные прокси, трафик через которые выглядит как обычный человек, листающий карточки с дивана. Заодно выяснилось, что цена на Ozon лежит прямо в серверном HTML, ещё до отработки скриптов. Никакого тяжёлого JS-движка - данные в первом же ответе сервера.
Война за трафик: от 30 мегабайт до 120 килобайт
Резидентный прокси считается по гигабайтам. Когда пришёл первый биллинг, стало не по себе: одна проверка цены одного товара тянула десятки мегабайт. Браузер честно качал всё подряд.
- Видео-CDN - по 23-25 МБ на проверку: крутящееся превью товара, которое никому не нужно ради одной цифры.
- JS-бандлы фронтенда - ещё 7-10 МБ, хотя цена давно лежит в HTML без всяких скриптов.
- После блокировки обоих слоёв одна проверка стала весить около 120 КБ - почти голая страница с нужными данными.
Снижение в двести раз. Разница между «прокси съедает всю экономику проекта» и «проектом можно вообще заниматься». Браузерная болтовня с серверами Google - синхронизация, push, токены - до конца так и не заглушена, но уровень вышел терпимый.
Wildberries: headless палится сразу
С резидентным IP Wildberries пускал. Но headless-браузер - тот, что без графического интерфейса и под автоматизацией, - упирался в антибот-челлендж. Причин набралось целый список.
- navigator.webdriver под автоматизацией возвращает true - у живого пользователя false.
- Список плагинов пуст, window.chrome.runtime отсутствует.
- В User-Agent торчит HeadlessChrome.
- На сервере без видеокарты WebGL отдаёт программный рендерер вместо реального GPU.
- enumerateDevices() возвращает пустой список вместо камеры и микрофона реальной машины.
Попытка «залатать» признаки через стелс-плагины упирается в стену: антибот проверяет не только значение, но и способ его получения. Переопределённое свойство видно по дескриптору, по цепочке прототипов, по свежему iframe. А управление через CDP - Chrome DevTools Protocol - само по себе оставляет тайминговые следы и аномалии в stack trace, которые не замаскировать никакими патчами на JS-уровне. Гонка, в которой ты по определению на шаг позади. Вывод прост: проще быть настоящим браузером, чем бесконечно притворяться им.