///
Как обходить антибот-защиту: TLS-фингерпринтинг и решение CAPTCHA
Владлен Власов
Владлен Власов
Технический писатель
10 апреля 2026 г.
10 мин
Пожалуйста, ознакомьтесь с правилами использования материалов на данном ресурсе.

Как обходить антибот-защиту: TLS-фингерпринтинг и решение CAPTCHA

generated-image (47).png

Современные антибот-системы, такие как Cloudflare, DataDome и Imperva, полагаются не только на CAPTCHA — они также анализируют TLS-фингерпринты, HTTP-процессы и согласованность характеристик браузера, чтобы выявлять роботизированный трафик.

Это означает, что для обхода WAF (Web Application Firewall) сегодня часто требуется нечто большее, чем стандартный HTTP-клиент: вам нужны TLS-фингерпринты, соответствующие браузеру, согласованные заголовки и надежный слой решения CAPTCHA.

В этом руководстве вы узнаете, как работает TLS-фингерпринтинг, почему JA3 и JA4 важны для обнаружения ботов и как такие инструменты, как tls-client и CapMonster Cloud, вписываются в современный стек для обхода антибот-защиты.

robots
Начните сейчас и автоматизируйте решение reCAPTCHA v2

Понимание TLS-фингерпринтинга: JA3, JA4 и обнаружение со стороны WAF

Когда ваш код выполняет HTTPS-запрос, TLS-рукопожатие раскрывает сведения о клиенте — поддерживаемые наборы шифров, расширения, эллиптические кривые и их порядок. Эта комбинация образует TLS-фингерпринт, который обычно фиксируется в виде JA3-хеша (на основе полей ClientHello) или JA4-фингерпринта (более нового, более структурированного формата, а не просто взаимозаменяемой альтернативы JA3).

Антибот-системы сравнивают этот фингерпринт с известными профилями. Стандартные HTTP-библиотеки, такие как Python requests, Node axios или Go net/http, создают фингерпринты, которые могут служить сильным сигналом небраузерного трафика — потенциально вызывая challenge или блокировку на edge/WAF-уровне ещё до того, как ваш запрос достигнет уровня приложения. Обратите внимание, что поставщики антибот-защиты обычно сочетают TLS-фингерпринтинг с рядом других технических, статистических и поведенческих сигналов.

Важно: TLS-фингерпринтинг часто является лишь одним слоем в многоэтапном конвейере препятствования ботам (точный набор слоёв зависит от конкретного провайдера защиты и конфигурации сайта). Даже если запрос проходит TLS-проверку, антибот-системы всё равно могут предъявить клиенту JavaScript-челенджи или CAPTCHA, поэтому требуется полноценный стек обхода проверок, а не просто подмена фингерпринта.


Как Cloudflare и DataDome используют TLS-рукопожатия для блокировки ботов

HTTP-клиенты по умолчанию предсказуемы. Сессия Python requests всегда согласовывает одни и те же наборы шифров в одном и том же порядке, что делает её надёжным сигналом для таких систем, как Cloudflare, DataDome и Imperva, позволяя отличать ботов от реальных браузеров в рамках их конвейера многофакторного анализа.

Это делает TLS-фингерпринтинг эффективным и недорогим фильтром первого слоя: он позволяет блокировать большую часть простой автоматизации до того, как потребуются вычислительные мощности на более глубокий поведенческий анализ.


Обход WAF с помощью TLS-клиентов, соответствующих браузеру

Чтобы пройти TLS-проверку, вам нужен клиент, который воспроизводит точные параметры рукопожатия реального браузера. Два варианта, которые стоит оценить:

  • tls-client (bogdanfinn) — библиотека на Go с готовыми профилями для Chrome, Firefox, Safari и Opera. Доступна как общая библиотека, которую можно использовать из Python, Node и других языков.
  • azuretls-client — альтернатива на базе Go с поддержкой браузерных профилей и сопоставлением HTTP/2-фингерпринтов. Перед использованием проверьте актуальный набор функций и статус сопровождения по документации в репозитории.

Обе библиотеки стремятся имитировать TLS-профили браузера на уровне сокета, однако точное соответствие реальной браузерной сессии не гарантируется — даже официальная документация tls-client отмечает, что ее внутренние профили не всегда могут на 100% совпадать с живым браузером.


Реализация на Python: настройка TLS-клиента для маскировки

При инициализации TLS-клиента используйте современный профиль Chrome и включайте рандомизацию порядка расширений. Точный строковый идентификатор каждого профиля может различаться в зависимости от версии библиотеки — всегда сверяйтесь с официальным списком профилей перед развёртыванием.

import tls_client
try:
    session = tls_client.Session(
        client_identifier="chrome_133",  # проверьте идентификатор в версии вашей библиотеки
        random_tls_extension_order=True
    )
    
    response = session.get(
        "https://target-site.com",
        timeout_seconds=30,
        headers={
            "User-Agent": (
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                "AppleWebKit/537.36 (KHTML, like Gecko) "
                "Chrome/146.0.0.0 Safari/537.36"
            ),
            "Accept-Language": "en-US,en;q=0.9,ru;q=0.8",
            "Accept-Encoding": "gzip, deflate, br, zstd",
        }
    )
    
    print(response.status_code)
    
except Exception as e:
    print(f"Request failed: {e}")

Ключевые параметры:

  • client_identifier="chrome_146" — указывает на профиль фингерпринта одной из недавних версий Chrome; всегда сверяйте этот идентификатор с официальным списком профилей для установленной у вас версии библиотеки.
  • random_tls_extension_order=True — снижает предсказуемость фиксированной последовательности расширений. Обратите внимание, что алгоритмы вроде JA4 нормализуют порядок расширений, поэтому само по себе это не является универсальной контрмерой против всех методов фингерпринтинга.
  • Всегда используйте соответствующие друг другу User-Agent и браузероподобные заголовки, чтобы избежать сигналов несоответствия на уровне HTTP-протокола.

robots
Начните сейчас и автоматизируйте решение reCAPTCHA v2

Слой решения CAPTCHA: интеграция CapMonster Cloud

Прохождение TLS-проверки необходимо, но не всегда достаточно. Такие платформы, как Cloudflare, DataDome и Imperva, работают послойно: после TLS они могут запросить JavaScript-челендж или CAPTCHA, чтобы убедиться, что клиент является реальным браузером. Несоответствие поведения на любом уровне приведёт к блокировке.

Именно здесь в стек вписывается CapMonster Cloud. Это облачный сервис для решения CAPTCHA с простым и понятным API, который обрабатывает типы челенджей, используемые этими антибот-системами:

Тип CAPTCHA / Challenge

Поддержка в CapMonster Cloud

Cloudflare Turnstile

Cloudflare Bot Challenge

✅ (требуется прокси)

DataDome CAPTCHA

✅ (требуется прокси)

Imperva / Incapsula

reCAPTCHA v2 / v3

Amazon WAF CAPTCHA

Общий рабочий процесс таков: ваш клиент, имитирующий TLS, обрабатывает транспортный уровень; CapMonster Cloud получает токен челенджа; затем вы вставляете этот токен в последующий запрос к серверам поставщика защиты. На практике успех зависит от конкретной конфигурации WAF и дополнительных сигналов, а не только от получения токена решенного челенджа.

Пример ниже охватывает Cloudflare Bot Challenge — распространённый сценарий, при котором защищённый сайт возвращает страницу 403 "Just a moment". В нём используется TurnstileTask с параметром cloudflareTaskType: "cf_clearance", который предназначен именно для потока Cloudflare Challenge — и отличается от обычной задачи Turnstile (используемой для автономных виджетов Turnstile). Всегда обращайтесь к актуальной документации CapMonster Cloud для уточнения точного набора обязательных полей, поскольку схема API может меняться от версии к версии.

import tls_client
import base64
import time
import requests
from urllib.parse import urlparse

# ===================== КОНФИГУРАЦИЯ =====================

API_KEY = "YOUR_CAPMONSTER_API_KEY"
TARGET_URL = "https://example.com/protected-page"
WEBSITE_KEY = "xxxxxxxxxx"

USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36"

# Proxy в формате: protocol://user:pass@ip:port
PROXY = "http://proxy_login:proxy_password@proxy_ip:proxy_port"

CREATE_TASK_URL = "https://api.capmonster.cloud/createTask"
GET_RESULT_URL = "https://api.capmonster.cloud/getTaskResult"

# ===================== TLS-СЕССИЯ =====================

session = tls_client.Session(
    client_identifier="chrome_120",
    random_tls_extension_order=True
)

session.headers.update({
    "User-Agent": USER_AGENT,
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Connection": "keep-alive",
})

session.proxies = {
    "http": PROXY,
    "https": PROXY
}

# ===================== ПАРСЕР PROXY =====================

def parse_proxy(proxy_url):
    parsed = urlparse(proxy_url)
    return {
        "proxyType": parsed.scheme,
        "proxyAddress": parsed.hostname,
        "proxyPort": parsed.port,
        "proxyLogin": parsed.username,
        "proxyPassword": parsed.password
    }

# ===================== ШАГ 1 =====================

def get_html_base64():
    try:
        resp = session.get(TARGET_URL, timeout_seconds=30)
        print(f"[INFO] Status: {resp.status_code}")

        html_base64 = base64.b64encode(resp.content).decode()
        print("[INFO] HTML Base64 received")
        return html_base64

    except Exception as e:
        print("[ERROR] Fetch HTML:", e)
        return None

# ===================== ШАГ 2 =====================

def solve_captcha(html_base64):
    proxy_data = parse_proxy(PROXY)

    payload = {
        "clientKey": API_KEY,
        "task": {
            "type": "TurnstileTask",
            "websiteURL": TARGET_URL,
            "websiteKey": WEBSITE_KEY,
            "cloudflareTaskType": "cf_clearance",
            "htmlPageBase64": html_base64,
            "userAgent": USER_AGENT,
            "proxyType": proxy_data["proxyType"],
            "proxyAddress": proxy_data["proxyAddress"],
            "proxyPort": proxy_data["proxyPort"],
            "proxyLogin": proxy_data["proxyLogin"],
            "proxyPassword": proxy_data["proxyPassword"]
        }
    }

    create = requests.post(CREATE_TASK_URL, json=payload).json()
    print("[INFO] CreateTask:", create)

    if create.get("errorId") != 0:
        raise Exception(create.get("errorDescription"))

    task_id = create["taskId"]
    print(f"[INFO] Task ID: {task_id}")

    while True:
        time.sleep(5)
        result = requests.post(GET_RESULT_URL, json={
            "clientKey": API_KEY,
            "taskId": task_id
        }).json()

        if result.get("status") == "ready":
            print("[INFO] Solution received")
            return result["solution"]

        print("[INFO] Waiting...")

# ===================== ШАГ 3 (ПРИМЕНИТЬ COOKIE) =====================

def apply_cookies(solution):
    """
    Применить cookie из решения CapMonster
    """
    # Вариант 1: список cookie
    if "cookies" in solution:
        for cookie in solution["cookies"]:
            session.cookies.set(
                cookie["name"],
                cookie["value"],
                domain=cookie.get("domain", ".example.com"),
                path=cookie.get("path", "/")
            )
        print("[INFO] Cookies applied from list")

    # Вариант 2: отдельный cf_clearance
    if "cf_clearance" in solution:
        session.cookies.set(
            "cf_clearance",
            solution["cf_clearance"],
            domain=".example.com",
            path="/"
        )
        print("[INFO] cf_clearance applied")

# ===================== ШАГ 4 (ДОСТУП К ЗАЩИЩЕННОЙ СТРАНИЦЕ) =====================

def access_protected_page():
    try:
        resp = session.get(TARGET_URL, timeout_seconds=30)
        print(f"[INFO] Final Status: {resp.status_code}")

        if "cf-chl" in resp.text or resp.status_code in [403, 503]:
            print("[WARNING] Still blocked by Cloudflare")
        else:
            print("[SUCCESS] Cloudflare bypass successful")

        return resp.text

    except Exception as e:
        print("[ERROR] Final request:", e)

# ===================== ОСНОВНОЙ КОД =====================

def main():
    html_base64 = get_html_base64()
    if not html_base64:
        return

    solution = solve_captcha(html_base64)
    print("\n=== CAPTCHA SOLUTION ===")
    print(solution)

    apply_cookies(solution)
    access_protected_page()

if __name__ == "__main__":
    main()

 CapMonster Cloud поддерживает задачи с использованием прокси для челенджей, требующих этого (Cloudflare Bot Challenge, DataDome). Указанный вами прокси влияет на IP-адрес, используемый при верификации, хотя итоговое принятие решения челенджа зависит от дополнительной логики внутри сервиса защиты.


Построение полного стека обхода антибот-защиты

Полноценный конвейер обхода для сайтов с современной антибот-защитой должен учитывать каждый уровень — хотя на практике многие провайдеры защиты комбинируют и по-разному взвешивают эти сигналы:

  • TLS-фингерпринтинг tls-client или azuretls-client с актуальным профилем Chrome и рандомизацией порядка расширений.
  • HTTP/2-фингерпринтинг → в документации этих же клиентов заявлена поддержка HTTP/2; проверьте поддержку настроек HPACK и stream в официальном README библиотеки.
  • Согласованность заголовковUser-Agent, Accept-Language, Sec-CH-UA и другие заголовки должны соответствовать выбранному профилю браузера.
  • CAPTCHA / JS-челенджиCapMonster Cloud API — охватывает Cloudflare Turnstile, Cloudflare Bot Challenge, DataDome, Imperva, reCAPTCHA и не только. Используйте правильный тип задачи для каждого челенджа: обычный Turnstile и Cloudflare Bot Challenge обрабатываются по-разному.
  • Репутация IP → для задач Cloudflare Bot Challenge и DataDome в CapMonster Cloud требуются резидентские или мобильные прокси; для других типов челенджей уточняйте требования к прокси в актуальной документации.

Обработка только одного уровня и игнорирование остальных — частая причина, по которой попытки обхода не работают на реальной практике. Большинство провайдеров используют несколько сигналов — для надёжного результата нужно учитывать их вместе.


Чеклист перед запуском веб-скрейпинга в продакш

  • Определите, какой провайдер антибот-защиты используется на целевом сайте (Cloudflare, DataDome, Imperva и т. д.)
  • Инициализируйте tls-client с актуальным профилем Chrome или Firefox; проверьте строковый идентификатор профиля по официальному списку
  • Включите random_tls_extension_order (это снижает предсказуемость фиксированной последовательности расширений, но само по себе не является полноценной мерой противодействия фингерпринтингу)
  • Установите HTTP-заголовки в соответствии с имитируемым браузером (User-Agent, Accept, Sec-CH-UA и т. д.)
  • Определяйте наличие CAPTCHA / челенджей в ответах (HTTP 403, HTML с "Just a moment", редирект через /cdn-cgi/)
  • Интегрируйте CapMonster Cloud API, используя правильный тип задачи для каждого челенджа: виджеты Turnstile используют TurnstileTask; Cloudflare Bot Challenge (cf_clearance) использует TurnstileTask с cloudflareTaskType: "cf_clearance" — проверяйте все обязательные поля по актуальной документации
  • Добавьте проверки errorId / errorCode во всех ответах CapMonster API
  • Добавьте timeout ко всем исходящим HTTP-вызовам; явно обрабатывайте исключения
  • Устанавливайте cookie cf_clearance с явным указанием domain и path
  • Используйте резидентские или мобильные прокси — они требуются для задач Cloudflare Bot Challenge и DataDome
  • Перед запуском в продакшн проверяйте свой TLS-фингерпринт с помощью сервиса tls.peet.ws или ja4db.com

NB: Пожалуйста, обратите внимание, что продукт предназначен для автоматизации тестирования исключительно ваших собственных веб-сайтов и ресурсов, к которым у вас есть законное право доступа.
ItGuy
geear
Партнёрская программа для разработчиков софта
Зарабатывайте до 30% от трат ваших пользователей на обход капчи
✅ Заявка отправлена
Спасибо за интерес к нашей партнёрской программе! Мы свяжемся с вами в течение 7 рабочих дней.
Заявка на подключение
Заполните форму, чтобы отправить заявку на подключение к партнёрской программе
Больше статей