Большинство скраперов терпят неудачу еще до того, как будет прочитан хотя бы один header.
Сервер анализирует TLS handshake (порядок наборов шифров, порядок расширений, предпочтения эллиптических кривых) и определяет, являетесь ли вы браузером или клиентской библиотекой, которая им притворяется. Python requests, net/http в Go, обычный curl: все они передают характерный fingerprint в момент установки соединения. Сайты, которые следят за этим (Datadome, Akamai, Imperva, защищенная часть Cloudflare), разрывают соединение или отдают страницу проверки (challenge page) еще до того, как значение User-Agent начнет играть роль.
Именно эту проблему решает unblocker: true на FourA. За последний месяц мы доработали компоненты, которые обеспечивают его стабильную работу.
Что нового
Флаг unblocker: true используется при любом вызове /api/single. Включите его, и мы сделаем три вещи: добавим набор browser headers, отправим request через curl-impersonate с TLS fingerprint реального браузера и декомпрессируем все, что вернет сервер (gzip, brotli, deflate). Первые две возможности были доступны еще в бета-версии. Третья (автодекомпрессия brotli) вышла 25 марта, а на следующий день мы добавили привязку к версии браузера, чтобы headers и TLS всегда соответствовали друг другу.
Как это работает
Вот как выглядит request:
curl -X POST "https://api.foura.ai/api/single" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://example.com/products",
"method": "GET",
"unblocker": true
}'
Под капотом работают три уровня.
Внедрение headers. Мы устанавливаем полный набор browser headers: User-Agent, Sec-Ch-Ua, Sec-Ch-Ua-Platform, Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest, Accept, Accept-Language и Accept-Encoding. Порядок имеет значение. Реальные браузеры отправляют их в определенной последовательности, и библиотеки обнаружения проверяют это.
TLS fingerprint. curl-impersonate 0.8.2 компилирует libcurl с BoringSSL и меняет порядок расширений TLS, чтобы он соответствовал тому, что целевая версия браузера отправляет в сеть. Ваши хэши JA3 и JA4 будут идентичны хэшам реальной сессии браузера. Стандартный curl, Python requests и net/http в Go создают fingerprints, которые автоматически блокируются за миллисекунды на защищенной инфраструктуре.
Автодекомпрессия. Когда unblocker включен, мы устанавливаем Accept-Encoding в значение gzip, deflate, br и позволяем libcurl распаковать body. Вы получаете обратно декодированную строку (или Buffer, если вы передаете returnBuffer: true). Никакой ручной обработки brotli, никаких несовпадений headers и body, когда сайт выбирает deflate вместо gzip.
Почему важна привязка к версии
TLS fingerprints жестко привязаны к версии. Порядок шифров в браузере в этом месяце отличается от порядка в прошлом месяце, и сайт, который тщательно проверяет fingerprints, заметит это расхождение. curl-impersonate поставляется с профилями для конкретных сборок браузеров, и мы привязываем наш бинарный файл реального браузера к той сборке, на которую в данный момент ориентирован curl-impersonate. Headers, объекты navigator и TLS сообщают одну и ту же версию.
Если это кажется слишком сложным, так оно и есть. Мы столкнулись с этой проблемой во время мартовской миграции на монорепозиторий, когда браузер автоматически обновился, и headers рассинхронизировались с curl-impersonate. Решение заняло два коммита: зафиксировать версию бинарного файла браузера и никогда не доверять менеджеру пакетов их синхронизацию.
Эффект
В ходе внутренних тестов на целях с жесткой проверкой fingerprints (финансы, туризм, защищенный e-commerce) разница между unblocker: false и unblocker: true означает разницу между challenge page и статусом 200. Обычный curl при запросе к защищенному Cloudflare сразу получает 403. Тот же URL с флагом unblocker: true проходит успешно, потому что TLS hello выглядит как handshake реального браузера.
Но для сайтов, которые не проверяют fingerprints (большинство публичных API, старые шаблоны CMS, любые ресурсы с ограничениями только по IP rate limits), можно не включать unblocker, что сэкономит несколько миллисекунд на согласовании TLS. Используйте его только тогда, когда это необходимо.
Для продвинутых пользователей
Несколько полезных паттернов.
Используйте unblocker вместе с residential proxy, если целевой ресурс также проверяет репутацию IP. IP-адреса дата-центров в сочетании даже с идеальным TLS handshake все равно будут заблокированы по ASN, которые сайт внес в черный список. Наш proxy endpoint (/api/proxy) ротируется по целевому домену, поэтому обычно достаточно добавить "proxy": "residential" в request.
Пропускайте unblocker при вызове JSON API, которым не важен браузер. Избыточные headers могут выглядеть подозрительно для API, который ожидает программного клиента, например, когда бэкенд вызывает собственный микросервис.
Если на сайте работает JavaScript-защита от ботов (интерактивные проверки Turnstile, Perimeter X на максимальных настройках, Akamai Bot Manager с включенной эвристикой), одного unblocker будет недостаточно. Вам понадобится browser endpoint, который запускает реальный Chromium и может пройти проверку. Это другой продукт с иной тарификацией, и мы подробно описали его в статье Browser Tasks: как скрапить сайты с большим количеством JavaScript.
Вы также можете комбинировать unblocker с блоком validate, чтобы отклонять responses, которые формально возвращают код 200, но содержат страницу проверки:
{
"url": "https://example.com/products",
"method": "GET",
"unblocker": true,
"validate": {
"data": { "fail": ["captcha", "Access Denied"] }
}
}
Это превращает скрытые сбои в классифицированные ошибки, что важно для отслеживания показателя успешности (success rate) в dashboard.
Что дальше
Браузеры выпускают новую стабильную версию каждые четыре недели. Разработчик curl-impersonate обычно обновляет инструмент месяцем позже, и мы обновляем наш стек вслед за ним. Вам не нужно ничего менять на своей стороне: unblocker: true продолжает указывать на ту версию браузера, которую мы протестировали от и до.
Впереди более сложная работа. HTTP/3 fingerprinting уже появляется в коммерческих системах защиты от ботов, транспортный протокол QUIC сложнее подделать, чем TLS 1.3, и начинается переход от статических наборов headers к по-настоящему динамической эмуляции. Защищенные сайты перешли на проверку порядка фреймов HTTP/2 и вариантов JA4+, и разрыв между «curl, который выглядит как браузер» и «реальным браузером» будет сокращаться с обеих сторон. Мы обязательно напишем об этом, когда выпустим обновление.