Тема 9: Анти-бот системы: Что такое TLS Fingerprint (JA3), и почему сервер видит, что я скрипт на Python, даже если я подменил User-Agent?
Представь ситуацию:
Ты купил элитные прокси. Ты поставил User-Agent от последнего Chrome. Ты скопировал все заголовки один в один.
Ты шлешь запрос на сайт... и получаешь 403 Forbidden или вечную проверку Cloudflare.
Почему? Потому что ты подделал "Паспорт" (User-Agent), но "Походка" (TLS Handshake) выдает в тебе робота.
1. Как происходит знакомство (TLS Handshake)
Когда твой браузер (или скрипт) соединяется с сайтом по HTTPS, первое, что он делает — это отправляет пакет ClientHello. Это как протянуть руку для приветствия. В этом пакете клиент говорит серверу: "Привет! Я умею общаться вот так:"
- Cipher Suites: Какие алгоритмы шифрования я поддерживаю (AES, ChaCha20...).
- TLS Version: TLS 1.2 или 1.3.
- Extensions: Всякие дополнительные фичи (Supported Groups, EC Point Formats, ALPN...).
СУТЬ ПРОБЛЕМЫ:
- Chrome предлагает одни алгоритмы и в строго определенном порядке.
- Python (библиотека
ssl+requests) предлагает совсем другой, куцый набор алгоритмов и в другом порядке.
2. Что такое JA3 Fingerprint?
Админы (Cloudflare, Akamai) придумали хитрую штуку.
Они берут весь этот список параметров из ClientHello, склеивают в строку и хешируют (MD5). Получается уникальный отпечаток — JA3.
- У настоящего Chrome отпечаток всегда один (например:
cd08e31494f9531f560d64c695473da9). - У стандартного Python requests он другой (например:
54328bd3642ff550a241459a03975051).
Ловушка захлопывается: Сервер смотрит:
- User-Agent: "Я Chrome на Windows!"
- JA3 Hash: "Я Python скрипт на Linux!"
- Вердикт: НЕСОВПАДЕНИЕ -> БОТ -> БАН.
Именно поэтому requests и aiohttp бесполезны против серьезных защит. Они не умеют менять свою "походку" (параметры SSL), потому что используют стандартную библиотеку OpenSSL, встроенную в Python.
3. Решение: Подмена отпечатка (Ciphers Impersonation)
Чтобы пройти фейс-контроль, нам нужно не просто подделать паспорт, но и научиться жать руку "по-пацански", как Chrome. Обычный Python этого не умеет. Нам нужны библиотеки, которые используют свой собственный SSL-движок.
Инструмент №1: curl_cffi (Топ выбор)
Эта библиотека использует модифицированную версию curl, которая умеет притворяться разными браузерами на уровне TLS.
from curl_cffi import requests
# impersonate="chrome120" — это команда:
# "Сформируй пакет ClientHello ТОЧНО так же, как Chrome 120"
response = requests.get(
"<https://tls.browserleaks.com/json>",
impersonate="chrome120"
)
# Сервер увидит JA3 от Chrome.
# User-Agent библиотека подставит сама (соответствующий хрому).
print(response.json())
Инструмент №2: tls_client
Это Python-обертка над Go-библиотекой. Тоже мощная, но curl_cffi сейчас поддерживается активнее.
🧪 ДИАГНОСТИКА: Как понять, что меня банят по TLS?
Есть простой тест.
- Возьми сайт, который тебя не пускает.
- Сделай запрос через обычный
requests(с подменой User-Agent).- Результат: 403?
- Сделай запрос через
curl_cffiсimpersonate="chrome".- Результат: 200 OK?
Вывод: Если пункт 3 сработал — проблема была именно в TLS Fingerprint. Добро пожаловать в клуб.
🧠 Резюме Архитектора:
В 2026 году парсить защищенные сайты (Avito, Amazon, Cloudflare-sites) обычным requests — это трата времени.
Если видишь защиту — сразу бери curl_cffi. Это сэкономит тебе часы гадания "почему меня забанили".