10 KiB
name, description, category, version, author, license
| name | description | category | version | author | license |
|---|---|---|---|---|---|
| cloudflare-bypass-scraping | Scrape Cloudflare sites. curl_cffi or full browser bypass. | automation | 1.0.0 | ENI/Gothbreach | MIT |
Cloudflare Bypass for Web Scraping
When to Use
- Target website returns Cloudflare "Checking your browser" or "Attention Required" interstitial
- Standard
requests/httpxgets 403 or empty response from a CF-protected site - Need to scrape emails, data, or content from sites behind Cloudflare
- Single-page or multi-page crawling with CF bypass
Two-tier approach for scraping websites protected by Cloudflare:
| Tier | Tool | When | Overhead |
|---|---|---|---|
| 1 — Lightweight | curl_cffi + impersonate="chrome124" |
90% of sites (TLS fingerprint check only) | Zero — pure HTTP |
| 2 — Full browser | CloudflareBypassForScraping server (CloakBrowser) | Sites with full JS challenge / Turnstile | 535 MB Chromium download, ~500 MB RAM |
Tier 1: curl_cffi (use first, works now)
curl_cffi impersonates Chrome's TLS/JA3 fingerprint at the HTTP library level. No browser, no JS engine — just TLS mimicry. Handles the "Checking your browser" interstitial on most CF-protected sites.
from curl_cffi import requests
resp = requests.get(
"https://protected-site.com",
impersonate="chrome124", # Chrome 124 TLS fingerprint
timeout=30,
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
},
)
html = resp.text
Install: pip install curl_cffi
Limitations: Does NOT execute JavaScript. Sites with Turnstile widget or full "5-second challenge" page will still block. Fall back to Tier 2.
Tier 1.5: Headless-Chrome fetch bridge (когда curl_cffi бессилен)
Симптом: API возвращает «invalid api key»/403/пустой ответ из curl, curl_cffi (ВСЕ impersonate-профили: chrome/chrome124/chrome131/safari/edge99), python requests — но тот же ключ через fetch() в реальном Chrome работает. IP одинаковый, заголовки не влияют. Значит backend сверяет JA3/TLS строже, чем умеет curl_cffi (проверено live: beta.pvacodes.com, 2026-09-19).
Решение: локальный HTTP-мост, проксирующий запросы через page.evaluate(fetch) в headless Chrome:
# pva_bridge.py — рабочий паттерн (Desktop/jiofarm_pva/pva_bridge.py)
# Playwright worker-поток + queue (greenlet-safe), ThreadingHTTPServer на 127.0.0.1
from playwright.sync_api import sync_playwright
# ВАЖНО: launch(headless=True, channel="chrome") БЕЗ доп. args и БЕЗ new_context(locale=...) —
# «чистый» launch прошёл TLS-гейт, а версия с --disable-blink-features и locale=en-US — нет.
# page.goto(origin) один раз, дальше page.evaluate(JS_FETCH, url) где
# JS_FETCH = "async (url) => { const r = await fetch(url, {credentials:'include'}); return await r.text(); }"
Greenlet-ловушка (обязательно): playwright sync_api НЕЛЬЗЯ вызывать из потоков ThreadingHTTPServer — «Cannot switch to a different thread». Паттерн: один daemon-worker владеет page, HTTP-handler кладёт (payload, result_box, threading.Event) в queue.Queue и ждёт event.wait(90).
Диагностика: если bridge отдаёт «api key inactive» хотя тест-скрипт работает — diff launch-параметров и проверь, что ключ в файле не замаскирован (см. masking pitfall в ai-provider-autoreg).
Когда bridge нужен с залогиненной сессией (дашборд-скрап) — добавь автологин (fill email/password + submit + wait_for_selector(visible) из-за CSS fade-in) и credentials:'include' в fetch.
Tier 2: CloudflareBypassForScraping Server
Full Chromium browser (CloakBrowser — stealth-patched Chromium 146) that solves the JS challenge, then caches cf_clearance cookies. Subsequent requests are instant.
Repo: https://github.com/sarperavci/CloudflareBypassForScraping (2.5k stars, MIT)
Setup
git clone https://github.com/sarperavci/CloudflareBypassForScraping.git
cd CloudflareBypassForScraping
pip install -r server_requirements.txt
⚠️ Hermes PYTHONPATH pitfall
Hermes sets PYTHONPATH to the old hermes-agent-0.18.2-latest venv which has playwright files locked (PermissionError). The CF bypass server needs playwright. Always run with PYTHONPATH= cleared:
PYTHONPATH= python server.py --port 8000
First run downloads CloakBrowser Chromium (~535 MB) from GitHub releases. This takes 5-10 minutes. Subsequent starts are instant.
Run
cd CloudflareBypassForScraping
PYTHONPATH= python server.py --port 8000 --log-level info
API Endpoints
/html — Get rendered HTML after CF bypass:
curl "http://localhost:8000/html?url=https://nopecha.com/demo/cloudflare"
/cookies — Get cf_clearance cookies only:
curl "http://localhost:8000/cookies?url=https://protected-site.com"
# Returns: {"cookies": {"cf_clearance": "..."}, "user_agent": "..."}
Mirror mode — proxy any request through the server:
curl "http://localhost:8000/api/data" \
-H "x-hostname: protected-site.com" \
-H "x-proxy: http://user:pass@proxy:port" # optional upstream proxy
Control headers
| Header | Purpose |
|---|---|
x-hostname |
Target hostname (required) |
x-proxy |
Upstream proxy URL (optional) |
x-bypass-cache |
Set to true to force fresh cookie generation |
Docker (alternative)
docker compose pull && docker compose up -d
Integration pattern: email scraper
See templates/email_scraper_cf.py for a complete example that:
- Tries
curl_cffifirst (Tier 1) - Falls back to CF Bypass Server (Tier 2) via
--backend server - Crawls internal links, extracts emails, saves to JSON
- Supports
--proxy,--quick(single page),--depth N
# Quick scan with curl_cffi
PYTHONPATH= python email_scraper_cf.py https://target.com --quick
# Full crawl with CF bypass server
PYTHONPATH= python email_scraper_cf.py https://target.com --backend server
# With residential proxy
PYTHONPATH= python email_scraper_cf.py https://target.com --proxy socks5://user:pass@host:port
Decision flowchart
Is the site behind Cloudflare?
├── No → use requests / httpx directly
└── Yes → try curl_cffi (impersonate="chrome124")
├── Got 200 with content → done
└── Got 403 / "Checking your browser" / challenge page
└── Start CF Bypass Server → use /html or mirror mode
Pitfalls
- First CF bypass server start downloads 535 MB — plan ahead, start it before the scraping session
- Hermes PYTHONPATH locks playwright — always
PYTHONPATH= pythonwhen running the server or scraper - curl_cffi impersonate versions —
chrome124is current; if sites start detecting it, trychrome120,chrome110,safari17_0 - CloakBrowser may trigger antivirus — it's a modified Chromium binary; whitelist the directory
- Cookie cache is per-worker — if using
--workers N, each worker has its own cache; cookies are regenerated per worker - Server uses significant RAM — ~500 MB per worker; use
--workers 1for scraping
Tier 3: remote stealth render (firecrawl) — для SPA+Turnstile и когда локальный IP режет ассеты
Если локальные браузеры показывают белый экран (SPA-бандл висит в pending / ERR_CONNECTION_RESET), а curl и firecrawl качают тот же ассет с 200 — проблема в выходном IP, не в сайте. Работай через firecrawl_scrape/firecrawl_interact со stealth-прокси. Детали лимитов interact (60s MCP-таймаут, сессия живёт ~1-2 мин, лимит 2 джобов, паттерн Turnstile-регистрации) — references/firecrawl-interact-turnstile-reg.md.
Tier 2.5: TRAWL — self-hosted FlareSolverr-killer (Bun + Camoufox + Redis + MCP)
Repo: https://github.com/germondai/trawl (AGPL-3.0, 979 stars, v1.8.0 08.10.2026 — активная разработка). Docs: https://docs.trawl.germondai.com
Когда: нужен ДОЛГОЖИВУЩЙ сервер обхода (не разовый скрипт) — парсинг под нагрузкой, *arr-стек (Prowlarr/Jackett/Sonarr), интеграция с AI-агентами через MCP. Многопрофильный: Cloudflare Turnstile/Interstitial, Akamai Bot Manager, Imperva/Incapsula, GeeTest Slide, Friendly Captcha v1/v2, ALTCHA, reCAPTCHA v2 (бесплатный audio через локальный Whisper), CAP proof-of-work. Всё локально, 2Captcha — опциональный fallback.
4-уровневая эскалация: Tier 0 plain HTTP → Tier 1 cached browser session (Redis) → Tier 2 fresh solve в Camoufox → Tier 3/4 (residential) proxy.
Деплой: git clone https://github.com/germondai/trawl && cd trawl && cp .env.example .env && docker compose up -d. API :8191 (/health, /scrape, FlareSolverr-compat /v1), MITM-прокси :8192 (MITM_ENABLED=true), MCP /mcp (MCP_ENABLED=true, Streamable HTTP: markdown/JSON-extract/screenshots/diagnostics). Дашборд :8191/dashboard. Первый старт 15-30с (browser pool warmup).
Детали и curl-примеры: references/trawl-flaresolverr-replacement.md.
Related skills
anti-detection-browser— browser automation for signup/registration flows (DrissionPage, nodriver)bpproxy— residential proxy generation for IP rotationpaywall-bypass— bypassing paywalls on news sites