Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cf-solver

Python License: MIT Local No paid API

A local Cloudflare solver. Clear a protected URL in one call — on your own proxy — and keep scraping pure-request. No paid solver service; the browser only runs when a real challenge is actually served.

from solver import Solver

res = Solver().get("https://target.com", proxy="http://user:pass@host:port")
print(res.status, res.solved_by)      # 200 direct  |  200 browser
print(res.cf_clearance, res.user_agent)
html = res.text

How it works

Three layers, so the expensive one (a browser) only runs when it has to:

  1. Fingerprint — a request with a browser-exact TLS + HTTP/2 fingerprint (curl_cffi). The passive JA3/HTTP2 block that accounts for most "Cloudflare 403" clears here in ~50 ms, with no browser.
  2. Detect — classify the response: clean, Cloudflare JS/managed challenge, Turnstile, reCaptcha v2/v3, or hCaptcha.
  3. Harvest — only for a genuine challenge: a stealth Chromium (patchright) runs locally, on the same proxy, executes Cloudflare's own JS, passes the interstitial, and returns the cf_clearance cookie + page. The browser lives in a subprocess (isolated event loop, hard timeout) and presents a consistent Windows fingerprint (UA + client-hints + navigator.platform).

The harvested cf_clearance + User-Agent are then handed back to curl_cffi, so further requests on the same (host, proxy) are fast and pure-request.

Bring your own proxy

cf_clearance is bound to the exit IP + User-Agent. The browser and the request client must therefore share the same proxy, or the cookie is rejected. You pass the proxy per call; the clearance is cached per (host, proxy).

Install

pip install -r requirements.txt
patchright install chromium

Library

from solver import Solver

solver = Solver()                       # clearance cached across calls
res = solver.get(url, proxy=proxy)      # or solver.post(url, proxy=proxy, data=...)

res.status        # HTTP status
res.solved_by     # "direct" (fingerprint) | "browser" | "failed"
res.challenge     # detected challenge kind, if any
res.cf_clearance  # cookie value, when Cloudflare issues one
res.cookies       # full cookie dict for reuse
res.user_agent    # UA the clearance is bound to
res.text          # response body

HTTP API

Run the solver as a service — the caller passes a URL and their own proxy:

python server.py                        # http://localhost:8000
API_KEY=secret python server.py         # require X-API-Key / Bearer
curl localhost:8000/solve -H 'Content-Type: application/json' -d '{
  "url":   "https://target.com",
  "proxy": "http://user:pass@host:port"
}'
# -> {"status":200,"solved_by":"browser","cf_clearance":"...","cookies":{...},
#     "user_agent":"...","body":"<!doctype html>...","ok":true}

What it detects

Guard Handling
Passive JA3 / HTTP2 403 Fingerprint layer — no browser
Cloudflare JS / managed challenge Local browser harvest → cf_clearance reuse
Cloudflare Turnstile Local browser harvest
reCaptcha v2 / v3, hCaptcha Detected + reported (attach your own token source)

Scope

  • Everything runs on your machine — no third-party solver API.
  • The fingerprint layer clears passive blocks outright; the browser layer clears the interactive Cloudflare challenge and hands off a reusable cookie.
  • reCaptcha / hCaptcha are detected (site-key + type) but not solved here — pair the detection with your own token source.

Disclaimer

Provided as is, for lawful automation, testing, and research. You are solely responsible for complying with the terms and laws of the sites you access.

License

MIT — see LICENSE.

About

Local Cloudflare solver — fingerprint pass + local browser challenge harvest + cf_clearance reuse. Bring your own proxy, no paid API.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages