Selenium спалится за 3 секунды

Если вы пытались спарсить сайт на Cloudflare через Selenium или Playwright и упёрлись в бесконечный «Verify you are human» — дело не в вашем коде. Дело в том, что Cloudflare палит автоматизацию браузера ещё до того, как отработает первая строчка JS‑скрипта.

Что на самом деле проверяет Cloudflare

Большинство думает, что Cloudflare анализирует поведение — движения мыши, скорость скролла. Это не так, точнее — не главное. Первый и самый жёсткий фильтр — это TLS‑отпечаток (JA3) и HTTP/2-отпечаток запроса, снятые ещё на этапе рукопожатия, до того как сервер отдал хоть байт HTML.

У requests, urllib, httpx — свой, «питоновский» TLS‑отпечаток. У headless Chrome, даже настоящего, есть свои маркеры: navigator.webdriver, порядок и набор TLS‑расширений, CDP‑биндинги, которые Cloudflare Bot Management распознаёт пачками. Отпечаток не совпадает с отпечатком живого Chrome у живого пользователя — вы получаете челлендж‑страницу вместо контента.

Пример 1: Selenium (не сработает)

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.cat.com/")
h2 = driver.find_element(By.TAG_NAME, "h2").text
print(h2)
driver.quit()

Результат — не текст H2, а "Just a moment..." или зависание на проверке. Даже настоящий Chrome под управлением Selenium несёт маркеры автоматизации на уровне CDP‑протокола, и Cloudflare Bot Management отличает его от живого браузера ещё до рендера страницы.

Пример 2: curl_cffi (сработает)

from curl_cffi import requests
from bs4 import BeautifulSoup
r = requests.get("https://www.cat.com/", impersonate="chrome124")
soup = BeautifulSoup(r.text, "html.parser")
print(soup.find("h2").text.strip())

# output - AFRICA & MIDDLE EAST

curl_cffi — обёртка над curl-impersonate, которая на уровне сокета воспроизводит TLS/JA3 и HTTP/2 отпечаток реального Chrome. Никакого браузера, никакого рендеринга JS, никакого челленджа — сервер видит рукопожатие, неотличимое от настоящего пользователя, и отдаёт страницу напрямую.

Методы применения curl_cffi

  • impersonate= — выбор личности браузера (chrome110chrome124edge99safari15_3 и так далее). Именно этот параметр подменяет TLS/JA3 и HTTP/2 отпечаток.

  • Session() — держит один и тот же отпечаток и куки на серии запросов. Cloudflare следит за консистентностью сессии — рваные identity между запросами тоже палево.

  • proxies= — работает так же, как в requests; для устойчивого скрапинга нужны ротируемые резидентские прокси, TLS‑маскировка одна их не заменяет.

  • Порядок заголовков — curl_cffi сохраняет реальный регистр и порядок заголовков браузера, а не алфавитную сортировку requests, которая сама по себе является меткой бота.

  • AsyncSession — асинхронный клиент для параллельного сбора без потери отпечатка на каждом потоке.

Где брать цели для тренировки

Cloudflare стоит не только перед cat.com — список сайтов на Cloudflare для практики: trends.builtwith.com/websitelist/Cloudflare.

Удачного парсинга!