Skip to main content

Bypassing Cloudflare with FlareSolverr

UpdatedMay 13, 2026

FlareSolverr Guide: Bypassing Cloudflare With Python (2026)

TL;DR — FlareSolverr is a Dockerised proxy server that runs Chromium with undetected-chromedriver to solve Cloudflare challenges and return the resulting HTML and cookies. The recommended pattern is to use it sparingly: clear the Cloudflare challenge once, capture the cookies + User-Agent, then make subsequent requests with normal Python Requests.

In this guide we'll walk through how to set up and use FlareSolverr from Python, including:

For other approaches to bypassing Cloudflare, see our How to Bypass Cloudflare guide.

Open-source bypass tradeoffs

Cloudflare continuously evolves its anti-bot protection, so open-source bypasses like FlareSolverr can occasionally fall behind a Cloudflare update and need an upstream fix. If you need a Cloudflare bypass with an SLA you can rely on against the strictest configurations, consider a managed smart-proxy bypass (see Alternatives To FlareSolverr).

Need help scraping the web?

Then check out ScrapeOps, the complete toolkit for web scraping.


Quick reference: FlareSolverr at a glance

AspectDetail
What it isAn HTTP proxy server that runs Chromium + undetected-chromedriver and exposes a JSON API on port 8191.
DistributionOpen source, distributed as a Docker image (ghcr.io/flaresolverr/flaresolverr:latest).
What it solvesCloudflare IUAM / "Just a moment..." interstitial challenges; some Turnstile challenges.
What it doesn't solveDataDome, PerimeterX/HUMAN, Akamai, Imperva. Different bot products need different bypasses.
Recommended patternUse it to bootstrap valid Cloudflare cookies, then scrape with Python Requests using those cookies + UA + IP.
CostFree to run; CPU/RAM cost of a headless browser per concurrent request.
Failure modesCloudflare ships a detection update that out-paces the bypass; per-domain success rates vary.

What Is FlareSolverr?

FlareSolverr is an open-source proxy server, distributed as a Docker image, that helps you bypass Cloudflare's anti-bot protection so you can scrape data from websites hosted behind Cloudflare's CDN.

It allows your scrapers to clear Cloudflare's anti-bot challenge pages like the one below:

How To Bypass Cloudflare - Challenge Page

Cloudflare uses numerous browser fingerprinting challenges and behavioural checks (more detail here) to decide whether a request is from a real user or a scraper.

Under the hood, FlareSolverr starts an HTTP server that drives Chromium with undetected-chromedriver to solve Cloudflare's JavaScript and browser-fingerprinting challenges by impersonating a real web browser. It opens the target URL in the headless browser, waits until the Cloudflare challenge clears, and returns the resulting HTML and the cookies the browser received.

Those cookies can then be reused with a lighter HTTP client like Python Requests — the recommended pattern, because it avoids paying the per-request cost of a full browser for every page you scrape.


How To Install Docker

As the easiest way to setup FlareSolverr is using Docker (as it already contains the Chromium browser), in this guide we will first show you how to install Docker.

So if you haven't Docker installed already then use one of the following links to install Docker:

Download the Docker installation package, and follow the instructions. Your computer may need to restart after installation.

After installation, if Docker isn't running then click the Docker Desktop icon. You can check that docker is by running the command in your command line:


docker

If it is recognized then you should be good to go.


Install & Run FlareSolverr

Next we need to get FlareSolverr up and running.

1. Download FlareSolver

First we need to download the FlareSolverr Docker image, which we can do by running the following command on Windows or Max OS:


docker pull flaresolverr/flaresolverr

Or on a Linux machine:


sudo docker pull flaresolverr/flaresolverr

If everything has worked correctly, when you open you Docker Desktop on the Images tab you should see the flaresolverr/flaresolverr image (or ghcr.io/flaresolverr/flaresolverr image depending on which option you used).

Python Web Scraping Playbook - FlareSolverr Docker Desktop Installed


2. Run FlareSolverr

To run FlareSolverr, we need to run the following command in our command line again.

For Windows and Max OS:


docker run -d \
--name=flaresolverr \
-p 8191:8191 \
-e LOG_LEVEL=info \
--restart unless-stopped \
ghcr.io/flaresolverr/flaresolverr:latest

For Linux:


sudo docker run -d \
--name=flaresolverr \
-p 8191:8191 \
-e LOG_LEVEL=info \
--restart unless-stopped \
ghcr.io/flaresolverr/flaresolverr:latest

To check that FlareSolverr is running correctly, go to http://localhost:8191/ and you should see get a response like this.


{
"msg": "FlareSolverr is ready!",
"version": "3.0.2",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}

If you do then, the FlareSolverr server is up and running correctly.


Use FlareSolverr With Our Scrapers

When running, FlareSolverr provides a simple HTTP server that we can send the urls we want to scrape to it, and FlareSolverr will send the request via a Selenium browser and undetected-chromedriver to solve the Cloudflare challenge and return the HTML response and the cookies.

Here is a example of using FlareSolverr to scrape PetsAtHome.com a Cloudflare protected website:


curl -L -X POST 'http://localhost:8191/v1' \
-H 'Content-Type: application/json' \
--data-raw '{
"cmd": "request.get",
"url":"https://www.petsathome.com/",
"maxTimeout": 60000
}'

Here is the same example using Python Requests instead of cURL to send the request to FlareSolverr:


import requests

post_body = {
"cmd": "request.get",
"url":"https://www.petsathome.com/",
"maxTimeout": 60000
}

response = requests.post('http://localhost:8191/v1', headers={'Content-Type': 'application/json'}, json=post_body)

print(response.json())

The response should look something like this:


{
"status": "ok",
"message": "Challenge solved!",
"solution": {
"url": "https://www.petsathome.com/",
"status": 200,
"cookies": [
{
"domain": "www.petsathome.com",
"httpOnly": false,
"name": "WC_MOBILEDEVICEID",
"path": "/",
"secure": false,
"value": "0"
},
{
"domain": ".petsathome.com",
"expiry": 1673531559,
"httpOnly": false,
"name": "FPLC",
"path": "/",
"secure": true,
"value": "k03jwEFLbwxG2InqkF8yDy5%2BxWFeypsVETpfQGAFNO9M33HudoClDsp%2FY9BH89yLrGpQRLYL2WCgOkBrWRwdcK%2BycvG8%2F3m3SjDu3ZDXXHodwcxEhm4fQo7x8G%2BMrw%3D%3D"
},
...
],
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
"headers": {},
"response": "<html><head>...</head><body>...</body></html>"
},
"startTimestamp": 1673459546891,
"endTimestamp": 1673459560345,
"version": "3.0.2"
}

As you can see FlareSolverr has successfully solved the Cloudflare challenge "message": "Challenge solved!" and returned the cookies and HTML response from the website.

This functionality gives us two ways to use FlareSolverr:

  • Option 1: Send all requests via FlareSolverr and leave it deal with any Cloudflare challenges.
  • Option 2: Use FlareSolverr to retrieve valid Cloudflare cookies that we can then use with other HTTP clients like Python Requests.

Option 1 is the simplest of the two options as you can just send the URLs you want to scrape to your FlareSolverr server and leave it deal with Cloudflare. However, as browsers are memory & bandwidth intensive using this approach can be unreliable and expensive when done at scale.

Option 2 is a small bit trickier, but a more reliable and cost effective approach if you intend to scrape at scale.

We will run through how to use both options below.


Option 1: Send All Requests To FlareSolverr

The first option is to send all the URLs you want to scrape to FlareSolverr and have it manage bypassing Cloudflare and handling the session cookies for you.


import requests

url_list = [
'https://www.petsathome.com/',
'https://www.petsathome.com/cats',
]

for url in url_list:
post_body = {
"cmd": "request.get",
"url": url,
"maxTimeout": 60000
}

## Send Request To FlareSolverr
response = requests.post('http://localhost:8191/v1', headers={'Content-Type': 'application/json'}, json=post_body)
if response.status_code == 200:
json_response = response.json()
if json_response.get('status') == 'ok':
html = json_response['solution']['response']
## ...parse data from response
print('Success')

This will work but it make your scraper slower, more expensive and unreliable to run as every request will be going through the Selenium browser.


Option 2: Use FlareSolverr To Only Retrieve Valid Cloudflare Cookies

The other option is to use FlareSolverr to retrieve valid Cloudflare cookies after passing the Cloudflare challenge and then using these cookies with another HTTP client to scrape the subsequent pages you want to scrape.

This is the recommended way of using FlareSolverr but is a small bit trickier.


import requests

post_body = {
"cmd": "request.get",
"url":"https://www.petsathome.com/",
"maxTimeout": 60000
}

response = requests.post('http://localhost:8191/v1', headers={'Content-Type': 'application/json'}, json=post_body)

if response.status_code == 200:
json_response = response.json()
if json_response.get('status') == 'ok':

## Get Cookies & Clean
cookies = json_response['solution']['cookies']
clean_cookies_dict = {cookie['name']: cookie['value'] for cookie in cookies}

## Get User-Agent
user_agent = json_response['solution']['userAgent']

## Make normal request
headers={"User-Agent": user_agent}

response = requests.get("https://www.petsathome.com/", headers=headers, cookies=clean_cookies_dict)
if response.status_code == 200:
## ...parse data from response
print('Success')


Here we make the request with FlareSolverr to retrieve valid Cloudflare cookies after passing the Cloudflare challenge then we:

  1. Extract & clean the valid Cloudflare cookies
  2. Extract the user-agent FlareSolverr used to get the cookies
  3. Make a new requests with Python Requests using the FlareSolverr cookies & user-agent to avoid triggering the Cloudflare challenge
User-Agents & IP Addresses

The Cloudflare cookies are linked to the user-agent and IP address that FlareSolverr used when solving the Cloudflare challenge so you need to make sure to use the same user-agent and IP address when making subsequent requests with a different HTTP client.


Controlling FlareSolverr Sessions

FlareSolverr supports persistent browser sessions so you can keep an authenticated Chromium instance alive across multiple requests. This is useful for several reasons:

  • You only pay the cost of opening Chromium once per session, not per request.
  • You can attach a specific proxy to a session — important when you're rotating proxy IPs, because Cloudflare cookies are bound to the IP address that solved the original challenge.
  • You can keep a logged-in session warm for sites that require auth on top of Cloudflare.

There are three relevant endpoints exposed by the FlareSolverr /v1 API:


import requests

API = "http://localhost:8191/v1"

# Create a session
r = requests.post(API, json={"cmd": "sessions.create", "session": "my-session"})
print(r.json())

# Reuse the session in a request — pass the session id
r = requests.post(API, json={
"cmd": "request.get",
"url": "https://www.petsathome.com/",
"session": "my-session",
"maxTimeout": 60000,
})
print(r.json()["solution"]["status"])

# Destroy the session when you're done
requests.post(API, json={"cmd": "sessions.destroy", "session": "my-session"})

If you are scraping a Cloudflare-protected site through a pool of proxy IPs, create one FlareSolverr session per IP and tag your requests with the right session so each cookie is reused on the same IP that originally solved its challenge — otherwise Cloudflare will spot the IP change and re-challenge.

Sessions are stored in memory by the FlareSolverr container, so they're cleared if the container restarts. For long-lived scrapers, treat session creation as part of your startup flow and recreate sessions on restart.


Making POST Requests With FlareSolverr

FlareSolverr also allows you to make POST requests to Cloudflare protected websites if you need to retrieve valid Cloudflare cookies from POST endpoints.

To do so, you simply need to use request.post instead of request.get in the cmd section of the FlareSolverr post body, and add any POST data you need to send in the postData value of the POST data:


import requests

post_body = {
"cmd": "request.post",
"url":"https://www.example.com/POST",
"postData": POST_DATA,
"maxTimeout": 60000
}

response = requests.post('http://localhost:8191/v1', headers={'Content-Type': 'application/json'}, json=post_body)

print(response.json())

The postData must be a string with application/x-www-form-urlencoded. Eg: a=b&c=d.


Alternatives To FlareSolverr

FlareSolverr is a powerful tool, but open-source bypasses periodically lag behind Cloudflare updates. If you'd rather not depend on a tool that may need an upstream fix when a Cloudflare detection update lands, there are three modern alternatives worth knowing in 2026:

1. TLS impersonation (lightest weight)

If the Cloudflare configuration you're hitting only relies on TLS fingerprinting and HTTP/2 settings, you don't need a headless browser at all. Use curl_cffi in Python, or scrapy-impersonate inside Scrapy, to make wire-level browser-impersonated requests. See the TLS Fingerprinting section in our 403 guide.

2. Embedded fortified browser (no Docker)

undetected-chromedriver and its successor nodriver embed the same browser-fortification techniques FlareSolverr uses, but inside your Python process — no separate Docker container needed. This is a good middle ground when you want full browser capability and a simpler operational footprint than running a FlareSolverr server.

3. Managed smart-proxy bypass (no maintenance)

ScrapeOps Proxy Aggregator integrates over 20 smart proxy providers behind one API and exposes Cloudflare bypasses as a request flag. Because the bypasses are developed and maintained by proxy companies financially motivated to stay ahead of Cloudflare, the success rate tracks closer to the leading edge — no patch-waiting on your side.

You can activate the ScrapeOps Anti-Bot Bypasses by adding the bypass flag to your API request.

For example, the code below uses the Cloudflare bypass by adding bypass=cloudflare_level_1 to the request:


import requests

response = requests.get(
url='https://proxy.scrapeops.io/v1/',
params={
'api_key': 'YOUR_API_KEY',
'url': 'http://example.com/', ## Cloudflare protected website
'bypass': 'cloudflare_level_1',
},
)

print('Body: ', response.content)

tip

Cloudflare is the most common anti-bot system being used by websites today, and bypassing it depends on which security settings the website has enabled.

To combat this, we offer 3 different Cloudflare bypasses designed to solve the Cloudflare challenges at each security level.

Security LevelBypassAPI CreditsDescription
Lowcloudflare_level_110Use to bypass Cloudflare protected sites with low security settings enabled.
Mediumcloudflare_level_235Use to bypass Cloudflare protected sites with medium security settings enabled. On large plans the credit multiple will be increased to maintain a flat rate of $3.50 per thousand requests.
Highcloudflare_level_350Use to bypass Cloudflare protected sites with high security settings enabled. On large plans the credit multiple will be increased to maintain a flat rate of $4 per thousand requests.

The advantage of taking this approach is that you can use your normal HTTP client and don't have to worry about:

  • Fortifying headless browsers
  • Managing numerous headless browser instances & dealing with memory issues
  • Reverse engineering the anti-bot protection systems

As this is all managed within the ScrapeOps Proxy Aggregator.

You can get a ScrapeOps API key with 1,000 free API credits by signing up here.


Frequently Asked Questions

What is FlareSolverr?

FlareSolverr is an open-source proxy server, distributed as a Docker image, that bypasses Cloudflare's anti-bot protection by running a real Chromium browser with undetected-chromedriver. You send it a URL, it opens that URL in the headless browser, waits for the Cloudflare challenge to clear, and returns the final HTML and session cookies — which you can then reuse with a normal HTTP client.

FlareSolverr remains widely used, but effectiveness varies per site. It works well against lower-tier Cloudflare configurations and breaks more often against the stricter bot-management settings (interactive Turnstile, IUAM, behavioural checks). Cloudflare ships detection updates regularly, so any open-source bypass needs to wait on upstream fixes when those land. Check the project's GitHub issues for current per-domain notes and pair it with residential proxies for the best results.

The easiest install is via Docker. Pull the image with `docker pull ghcr.io/flaresolverr/flaresolverr:latest` and run it with `docker run -d --name=flaresolverr -p 8191:8191 --restart unless-stopped ghcr.io/flaresolverr/flaresolverr:latest`. Once the container is up, FlareSolverr exposes an HTTP API on port 8191 — POST a JSON body with the target URL to /v1 and you get back HTML plus cookies.

Usually no — running every request through a headless browser is slow and resource-intensive. The recommended pattern is to use FlareSolverr once per session to retrieve valid Cloudflare cookies, then make subsequent requests with Python Requests using those cookies plus the same User-Agent and outbound IP. This is faster and cheaper at scale.

Three modern alternatives: (1) curl_cffi or scrapy-impersonate for TLS-fingerprint-only targets without interactive challenges, (2) undetected-chromedriver or nodriver embedded directly in your scraper for a simpler operational footprint than running a separate Docker server, (3) a managed smart proxy API (e.g. ScrapeOps Proxy Aggregator with bypass=cloudflare_level_1/2/3) when you'd rather not maintain a Cloudflare bypass at all.

Cloudflare ties its session cookies to the IP address and User-Agent that solved the challenge. If you send subsequent requests from a different IP (e.g. a rotating proxy) or with a different UA, Cloudflare will reject the cookies and re-challenge. Solve this by creating one FlareSolverr session per outbound IP and reusing the captured User-Agent verbatim.


More Web Scraping Tutorials

In this guide we've introduced the fundamentals of FlareSolverr and shown how to use it in your own projects. For deeper coverage of Cloudflare bypass strategies in general, see:

If you'd like to learn more about web scraping in general, check out The Web Scraping Playbook.