Вы купили чистые резидентные IP, идеально их ротируете — и всё равно ловите 403 на первом же запросе. Дело не в IP — проблема в вашем TLS-рукопожатии. TLS-фингерпринтинг позволяет серверу опознать клиентскую библиотеку ещё до того, как будет прочитан хоть один байт вашего HTTP-запроса. В этой статье разберём JA3/JA4, покажем, почему Python-библиотека requests детектируется на раз, и дадим рабочий код, который выдаёт ваш клиент за настоящий браузер через curl_cffi и tls-client.
Когда любой клиент открывает HTTPS-соединение, он отправляет ClientHello, в котором заявляет версию TLS, наборы шифров, расширения, эллиптические кривые и порядок всего перечисленного. Этот порядок на удивление специфичен для библиотеки, которая его сформировала. Захешируйте его — и получите фингерпринт JA3 (или более новый и устойчивый JA4).
Chrome выдаёт один фингерпринт. Firefox — другой. Python-библиотека requests (построенная на urllib3 и OpenSSL) выдаёт фингерпринт, который буквально кричит «автоматизация» — и он одинаков у миллионов ботов. Анти-бот системы держат чёрный список таких отпечатков. Каким бы резидентным ни был ваш IP, известный «ботовский» JA3 будет помечен.
Прежде чем что-то чинить, измерьте это. Отправьте запрос из своего скрапера в бесплатный чекер фингерпринтов JA3/JA4 от JIBAO и сравните результат с тем, что показывает настоящий Chrome. Если хеши JA3 различаются, целевой сайт легко отличит вас от человека — и Cloudflare тоже.
requests и httpx отдают TLS системному OpenSSL. Можно сколько угодно менять заголовки и даже User-Agent, но рукопожатие под капотом всё равно от OpenSSL, а не от Chrome. Подмена заголовков без подмены рукопожатия — самая частая причина истории «я скопировал заголовки браузера, а меня всё равно блокируют». Нужен клиент, который имитирует реальный TLS-стек браузера.
curl_cffi привязан к curl-impersonate — сборке curl, которая воспроизводит TLS- и HTTP/2-фингерпринты настоящих браузеров. Один аргумент — и ваше рукопожатие выглядит как Chrome:
# pip install curl_cffi
from curl_cffi import requests
# выдаём себя за настоящий TLS + HTTP/2 фингерпринт Chrome
r = requests.get(
"https://tls.browserleaks.com/json",
impersonate="chrome131",
)
print(r.json()["ja3_hash"]) # теперь совпадает с настоящим Chrome
API повторяет requests, поэтому миграция существующего скрапера сводится в основном к замене одной строки импорта. Поддерживаются свежие сборки Chrome, Edge, Safari и Firefox — выберите одну и держите её актуальной, потому что фингерпринты меняются по мере обновления браузеров.
Совпадение фингерпринта и ротация IP — вещи дополняющие, а не взаимозаменяемые. Используйте оба: рукопожатие браузерного уровня поверх чистого резидентного IP — вот что реально проходит:
from curl_cffi import requests
PROXY = "socks5h://USERNAME:[email protected]:10001"
r = requests.get(
"https://example.com/protected",
impersonate="chrome131",
proxies={"http": PROXY, "https": PROXY},
timeout=30,
)
print(r.status_code)
tls-client (Python-обёртка над Go-реализацией uTLS) — ещё один надёжный вариант с большой библиотекой именованных профилей:
# pip install tls-client
import tls_client
session = tls_client.Session(
client_identifier="chrome_120",
random_tls_extension_order=True,
)
session.proxies = {
"http": "socks5h://USERNAME:[email protected]:10001",
"https": "socks5h://USERNAME:[email protected]:10001",
}
r = session.get("https://example.com/protected")
print(r.status_code)
random_tls_extension_order=True перемешивает порядок расширений, чтобы не давать статичный, переиспользуемый фингерпринт — полезно против систем, которые отслеживают точное совпадение JA3 во времени.
Некоторые цели проверяют сигналы исполнения JavaScript (canvas, WebGL, тайминги событий), которые не воспроизводит ни один HTTP-клиент. Там нужно управлять настоящим браузером — см. использование прокси с Playwright и Puppeteer в режиме stealth. Компромисс — цена и скорость: HTTP-клиенты вроде curl_cffi намного дешевле в пересчёте на запрос, поэтому используйте их везде, где их хватает, а полноценные браузеры держите для самых сложных целей.
curl_cffi (impersonate=) или tls-client — одних заголовков недостаточно.TLS-фингерпринтинг — недостающий слой в большинстве историй «IP чистый, а всё равно блокируют». Почините рукопожатие, сохраните резидентный IP — и доля успешных запросов резко вырастет. Полный стек против самых жёстких WAF читайте в рецепте обхода Cloudflare 2026.
Получите $5 бесплатного баланса и резидентные IP в пару к TLS-фингерпринтам браузерного уровня.
Начать бесплатноНовым пользователям — 5U при регистрации, бонус к первому пополнению. Акция ограничена по времени.