Ваш скрапер отправляет идеальные заголовки Chrome, работает через чистый резидентный IP — и всё равно ловит 403 на самом первом запросе. Ни капчи, ни страницы с челленджем, решать нечего. Сайт вычислил вас ещё до того, как был передан хоть один байт HTTP — во время TLS-рукопожатия.
В этой статье разбираемся, как на самом деле работает фингерпринтинг JA3 и JA4, почему это тихая рабочая лошадка каждой серьёзной анти-бот системы в 2026 году и как за десять секунд увидеть собственный отпечаток. Если вам сначала нужен инструментарий для обхода — об этом мы писали в статье Обход TLS-фингерпринтинга с curl_cffi и tls-client — а это парный материал о том, как устроена сторона детекции.
Прежде чем переходить к теории, взгляните на собственное рукопожатие. Откройте наш бесплатный чекер JA3/JA4 — он возвращает TLS-отпечаток, который ваш клиент только что предъявил, и говорит, чему он соответствует:
# Из терминала - посмотрите, как выглядит TLS у curl:
curl https://check.jibaoproxy.com/api/fingerprint
# Затем откройте тот же URL в Chrome и сравните.
Запустите оба варианта — и увидите смысл всей этой статьи: curl и Chrome дают совершенно разные отпечатки, какой бы заголовок User-Agent вы ни выставили.
Любое HTTPS-соединение начинается с сообщения ClientHello, которое отправляется открытым текстом до начала любого шифрования. В нём ваш клиент объявляет:
Вот ключевой момент для детекции: эти списки и их точный порядок зашиты в ту TLS-библиотеку, с которой собран ваш клиент. BoringSSL в Chrome объявляет одну конкретную комбинацию. OpenSSL в Python — другую. crypto/tls в Go — третью. Заголовками это не изменить — всё согласуется ниже уровня HTTP, самой библиотекой.
JA3 (Salesforce, 2017) склеивает пять полей ClientHello — версию TLS, шифры, расширения, кривые, форматы точек — в строку и берёт от неё MD5-хеш:
771,4865-4866-4867-49195-49199,0-23-65281-10-11-35-16,29-23-24,0
|
v MD5
cd08e31494f9531f560d64c695473da9
Один хеш на один TLS-стек. Каждая копия Chrome 137 на Windows даёт (почти) одинаковый JA3; каждый python-requests на OpenSSL 3.x даёт один и тот же, но другой JA3. Защитники ведут таблицы соответствий: хеш X = Chrome, хеш Y = requests, хеш Z = Go-бот. Если в User-Agent написано Chrome, а JA3 говорит OpenSSL — вас блокируют. Мгновенно, молча, дёшево.
У JA3 были проблемы: в 2023 году Chrome начал рандомизировать порядок расширений (ломая наивный JA3), а MD5 неструктурирован — один хеш ничего не говорит о том, почему два клиента различаются. JA4 (FoxIO, 2023) решил обе проблемы, и именно его сегодня используют серьёзные вендоры:
JA4 = t13d1516h2_8daaf6152771_b0da82dd1658
| | |
a: protocol b: ciphers c: extensions
(TLS 1.3, 16 ciphers, (sorted, truncated
h2 ALPN, domain SNI) SHA256)
Все, кто имеет значение: Cloudflare даёт доступ к JA3/JA4 прямо в правилах bot-management; DataDome и PerimeterX подают их в свой скоринг на сетевом уровне (см. наш гайд по DataDome/PerimeterX); Akamai занимается TLS-фингерпринтингом дольше всех. Метод популярен, потому что он бесплатен в вычислении, его невозможно подделать с уровня HTTP и он ловит 90% наивной автоматизации — каждый написанный скрипт на requests/httpx/axios/Go-http — ещё до того, как понадобится запустить хоть какой-то JavaScript.
Это удивляет людей: прокси меняет ваш IP, но ваше TLS-рукопожатие проходит сквозь него без изменений. CONNECT-туннель (или SOCKS5-поток) переносит байты вашего ClientHello к цели дословно. Резидентный IP + JA3 библиотеки requests = «бот, работающий на резидентном IP». Лучше, чем IP дата-центра, но всё равно бот.
IP и TLS-отпечаток — это независимые сигналы, и нужно, чтобы оба были чистыми:
| IP | TLS-отпечаток | Вердикт в 2026 |
|---|---|---|
| Дата-центр | Библиотека (requests/Go) | Блок везде, где это проверяют |
| Резидентный | Библиотека | Блок на сайтах с проверкой JA4 |
| Дата-центр | Имперсонация браузера | Блок по репутации IP |
| Резидентный | Имперсонация браузера | Проходит проверки сетевого уровня |
Два пути, в зависимости от инструментария:
HTTP-клиенты — используйте библиотеку имперсонации, которая воспроизводит точный ClientHello браузера: curl_cffi (Python), tls-client (Python/Go), got-scraping (Node). Полный рабочий код — в гайде по curl_cffi:
from curl_cffi import requests
r = requests.get(
"https://target.example",
impersonate="chrome",
proxies={"https": "socks5h://USERNAME:[email protected]:913"},
)
Настоящие браузеры (Playwright, браузерные агенты, анти-детект браузеры) — на уровне TLS делать нечего; отпечаток подлинно принадлежит Chrome. Ваш риск живёт в другом месте: репутация IP и детекция через CDP.
И ещё: проверяйте, не предполагайте. Версии дрейфуют — библиотека имперсонации, привязанная к рукопожатию Chrome 120, читается как «подозрительно устаревший браузер» в 2026 году. Перепроверяйте после каждого обновления зависимостей:
Соедините имперсонированный TLS с резидентными IP — $5 бесплатного баланса, без карты.
Начать бесплатноНовым пользователям — 5U при регистрации, бонус к первому пополнению. Акция ограничена по времени.