How to Solve Cloudflare With Python (Playwright + Scrapeless)
Expert Network Defense Engineer
TL;DR:
- Cloudflare scores the browser, not the visitor. It reads fingerprint consistency, behavioral signals, and the exit IP, then sets a
cf_clearancecookie for a browser it trusts β so solving it in Python means being a trusted browser, not answering a puzzle. - A local Python browser fails that scoring on three axes: the
navigator.webdrivertell, a headless-default fingerprint, and a datacenter exit IP. Patching all three by hand is a maintenance treadmill. - The Scrapeless Scraping Browser clears the challenge during render β real self-developed Chromium, a consistent per-session fingerprint, and residential egress in 195+ countries, reached over one WebSocket endpoint.
- Your Python stays standard Playwright. Connect with
chromium.connect_over_cdp(), wait for the post-challenge content, and read the page β the only change is the connection URL. - Verified live: a Python Playwright session over the cloud browser cleared the Cloudflare challenge page, read the success marker
You bypassed the Cloudflare challenge! :D, and received acf_clearancecookie. - Free to start. New Scrapeless accounts include free Scraping Browser runtime β sign up at app.scrapeless.com.
Introduction: solving Cloudflare in Python is a browser problem
A Cloudflare challenge is not an image CAPTCHA you decode. It runs in the background and grades the browser that loaded the page β whether the fingerprint is internally consistent, whether the interaction signals look human, and whether the exit IP has a clean reputation. When the score passes, Cloudflare sets a cf_clearance cookie and the real page loads. When it doesn't, you get an interstitial instead of content.
That reframes the Python task. There is no answer to submit β the work is presenting a browser Cloudflare already trusts. A local headless Chromium driven from Python can't: it announces automation through the navigator.webdriver property, ships headless-default fonts and canvas behavior, and exits from an IP reputation services already know. You can patch each of those and then keep patching as Chromium and the detectors move. This guide takes the shorter path: drive the Scrapeless Scraping Browser from standard Playwright for Python, so the fingerprint, behavior, and exit IP are handled server-side and the challenge clears during a normal render.
What Cloudflare actually checks
Cloudflare's own documentation describes a verification step that runs without interrupting the visitor. In practice it grades three things and grants a cf_clearance cookie β a standard HTTP cookie β when they pass:
| What Cloudflare reads | Why a local Python browser fails it |
|---|---|
| Fingerprint consistency | headless defaults and the webdriver flag contradict a real Chrome |
| Behavioral signals | scripted timing without a coherent browser surface |
| Exit IP reputation | datacenter IPs score worse than residential ones |
A coherent, trusted browser matters more than any single evasion β which is why moving all three server-side is more durable than stacking stealth patches.
Why Scrapeless Scraping Browser
The Scrapeless Scraping Browser is a customizable, anti-detection cloud browser designed for web crawlers and AI agents. For Cloudflare specifically, it brings:
- Real self-developed Chromium that runs the challenge JavaScript exactly like Chrome, so it resolves instead of stalling.
- A consistent per-session fingerprint β no
navigator.webdrivertell, no headless defaults leaking through. - Residential egress in 195+ countries β Cloudflare scores the exit IP, and a residential region reads clean where a datacenter IP does not.
- Session persistence so a
cf_clearancegrant can be reused across requests in the same session. - One connection surface β every option is a query parameter on the same WebSocket endpoint.
Get your API key on the free plan at app.scrapeless.com.
Prerequisites
- Python 3.10 or newer
- Playwright for Python (
pip install playwright) - A Scrapeless account and API key β sign up at app.scrapeless.com
Full connection details live in the Scraping Browser documentation.
Install
You connect to a remote browser, so you do not need to playwright install a local Chromium for this flow.
bash
pip install playwright
export SCRAPELESS_API_KEY=your_api_token_here # free key at https://app.scrapeless.com
Connect and clear the challenge
Build the endpoint, connect with chromium.connect_over_cdp(), navigate, and wait for the post-challenge content to attach. The challenge is solved during render β there is no separate solve call.
python
import json
import os
from urllib.parse import urlencode
from playwright.sync_api import sync_playwright
params = {"token": os.environ["SCRAPELESS_API_KEY"], "sessionTTL": "180", "proxyCountry": "US"}
endpoint = f"wss://browser.scrapeless.com/api/v2/browser?{urlencode(params)}"
TARGET = "https://www.scrapingcourse.com/cloudflare-challenge"
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(endpoint)
page = browser.new_page()
page.goto(TARGET, wait_until="domcontentloaded", timeout=90000)
# The cloud browser clears Cloudflare during render; wait for the real content.
page.wait_for_selector("#challenge-title", timeout=90000)
print("cleared:", page.inner_text("#challenge-title"))
cookies = page.context.cookies()
print("cf_clearance:", any(c["name"] == "cf_clearance" for c in cookies))
browser.close()
A live run of this script printed cleared: You bypassed the Cloudflare challenge! :D and cf_clearance: True β standard Playwright for Python, sourced through the cloud browser.
Get your API key on the free plan: app.scrapeless.com
Confirm the pass and carry the clearance
The reliable signal is the real content attaching β once the post-challenge element is present, the page cleared. Cloudflare also sets a cf_clearance cookie on the passing session, which you can read to carry the clearance to other requests in the same session.
python
cookies = page.context.cookies()
clearance = next((c for c in cookies if c["name"] == "cf_clearance"), None)
print("cf_clearance present:", clearance is not None)
if clearance:
print("domain:", clearance["domain"])
Pin the region for a reliable clear
Cloudflare scores the exit IP, so pin proxyCountry to a residential region. Turn it to any ISO country code.
python
params = {
"token": os.environ["SCRAPELESS_API_KEY"],
"sessionTTL": "180",
"proxyCountry": "US", # or "DE", "JP", "ANY"
}
Where local Python browsers stop
A local Playwright or requests-based scraper is fine until Cloudflare starts scoring the browser. Then the headless fingerprint, the webdriver flag, and the datacenter IP each fail a different check, and the interstitial replaces the content. Those are fingerprint, behavior, and IP problems β the three the cloud browser handles server-side. Connecting to Scrapeless hands them to a managed session while your Playwright code stays standard.
What you get back
The session behaves like any Playwright for Python session β page.goto, page.wait_for_selector, page.content(), and cookies all work. A few honest observations from clearing Cloudflare over the cloud browser:
navigator.webdriveris absent, so the first check Cloudflare runs reads like a real Chrome.- The exit IP matches
proxyCountryβ a residential region clears far more reliably than a datacenter IP. cf_clearanceis present after a pass β reuse the same session to carry the grant across follow-up requests.- Warm the session for stubborn pages β load the site's homepage first in the same session before the protected page, so the behavioral surface looks like a normal visit.
Conclusion: clear Cloudflare, keep your Python
Solving Cloudflare in Python is not about decoding a challenge β it is about presenting a browser Cloudflare trusts. The Scrapeless Scraping Browser handles the three things it scores (fingerprint, behavior, exit IP) server-side, so your Playwright for Python code changes only its connection URL. Pin proxyCountry to a residential region, wait for the post-challenge content, and read cf_clearance to confirm the pass. For running the same cloud browser with another Python library, see the Scrapling production-scraper guide, and compare plans on the Scrapeless pricing page.
Ready to Build Your Cloudflare-Clearing Pipeline?
Join our community to claim a free plan and connect with developers scraping Cloudflare-protected sites: Discord Β· Telegram.
Sign up at app.scrapeless.com for free Scraping Browser runtime and point Playwright for Python at the cloud browser that clears Cloudflare during render.
FAQ
Q: Do I need a separate CAPTCHA-solving service?
Not on a passing browser. Cloudflare mostly scores fingerprint, behavior, and IP in the background and issues a cf_clearance cookie. The cloud browser is built to pass that scoring during a normal render, so there is no separate puzzle step to wire up.
Q: Do I need a proxy?
No. Residential egress is built in β set proxyCountry to a region or ANY. Cloudflare scores the exit IP, so a residential region clears more reliably than a datacenter address.
Q: The challenge still shows on some pages β what helps?
Pin proxyCountry to a residential region and warm the session by loading the site's homepage first in the same session before the protected page, so the behavioral surface reads like a normal visit.
Q: Is my existing Playwright code compatible?
Yes. The Scraping Browser speaks CDP, so chromium.connect_over_cdp() works unchanged β you only change the connection URL.
Q: Is clearing Cloudflare legal?
Accessing publicly available data is generally permitted, but the rules vary by jurisdiction and site. Review the target's terms of service, respect robots directives, and consult counsel for anything sensitive.
At Scrapeless, we only access publicly available data while strictly complying with applicable laws, regulations, and website privacy policies. The content in this blog is for demonstration purposes only and does not involve any illegal or infringing activities. We make no guarantees and disclaim all liability for the use of information from this blog or third-party links. Before engaging in any scraping activities, consult your legal advisor and review the target website's terms of service or obtain the necessary permissions.



