Geonode logo
Geonode Team

Geonode Team

Updated: September 2, 2026

Published: 2026-09-02

Cloudscraper in Python: A Full Guide

Cloudscraper is a Python library for getting past Cloudflare's interstitial challenge page. It was genuinely effective, it is widely recommended, and it has not had a functional release since 2023. That gap matters more than any usage guide, because Cloudflare's detection has changed substantially in the intervening years and the library's own README describes a threat model that no longer exists. This article covers what it does, why the approach stopped working, and what to do instead.

We are Geonode and we sell proxies, which is the product usually suggested alongside a library like this. The honest position is that we are not going to write a bypass guide, and that in this specific case the tool has aged out anyway. We checked the package in September 2026: version 1.2.71 on PyPI, uploaded April 2023, with the source repository last touched in June 2025 and those commits being administrative rather than functional. Meanwhile Cloudflare's bot detection has moved to machine learning over billions of requests, JavaScript-based headless detection, and header-order analysis. A requests-based library that solves a JavaScript challenge is not addressing any of that. The useful part of this article is the last three sections.

What Cloudscraper Was Built For

The library's own description is clear about its target, and reading it now is instructive.

Cloudscraper describes itself as "a simple Python module to bypass Cloudflare's anti-bot page (also known as 'I'm Under Attack Mode', or IUAM), implemented with Requests". It notes that "Cloudflare's anti-bot page currently just checks if the client supports Javascript, though they may add additional techniques in the future".

The mechanism it was solving is the classic interstitial:

Checking your browser before accessing website.com.
This process is automatic. Your browser will redirect to your requested content shortly.
Please allow up to 5 seconds...

The library's approach was to use "a JavaScript Engine/interpreter to solve Javascript challenges", which "allows the script to easily impersonate a regular web browser without explicitly deobfuscating and parsing Cloudflare's Javascript". Its documentation notes that a script would "sleep for ~5 seconds for the first visit to any site with Cloudflare anti-bots enabled", with no delay afterwards.

For the problem as it existed, this was a reasonable design. The challenge was a JavaScript puzzle; the library ran a JavaScript engine and solved it.

The README also contains a commitment that dates the project precisely: "Cloudflare changes their techniques periodically, so I will update this repo frequently."

The Maintenance Position, Checked

Facts rather than impressions, verified in September 2026.

The latest PyPI release is 1.2.71, uploaded 25 April 2023. That is a gap of over three years against a target the author described as changing periodically.

The GitHub repository was last pushed in June 2025, and the most recent commits are titled "Fix owner", "re-add gitignore" and "Correct the owner details" — housekeeping rather than detection updates.

It is not archived, and it has around 36 open issues.

None of this is a criticism of the author, who wrote a useful tool and gave it away under an MIT licence. It is simply the state of the package, and it is the single most relevant fact for anyone about to depend on it. A library whose entire value proposition is keeping pace with an adversary is a library where the release date is the specification.

If you find cloudscraper recommended in an article, check the article's date. A great deal of the advice circulating was accurate when written and has not been revisited.

What Cloudflare Detection Looks Like Now

The reason the approach no longer works, from Cloudflare's own documentation.

Cloudflare's bot score runs from 1 to 99, where 1 means "Cloudflare is quite certain the request was automated" and 99 indicates a likely human. It is produced by several engines working together.

Machine learning accounts for most detections. Cloudflare describes a "supervised machine learning methodology" analysing billions of daily requests, examining "request features like headers and browser signals" to predict the probability that a client is human.

Heuristics match known signatures, assigning a score of 1 for high-confidence detections.

JavaScript detections identify headless browsers through "lightweight, invisible client-side JavaScript injection" that Cloudflare states "does not collect any personally identifiable information".

Detection IDs are static rules identifying predictable behaviour. Cloudflare's example is telling: they can identify when "a client sends headers in a different order than what its claimed browser would use".

That last one is the crux. Header order is not something a requests-based library controls, and it does not change when you solve a JavaScript challenge. Neither does the TLS handshake signature, which is a property of your Python HTTP stack rather than of anything you send.

So the model has inverted. In 2019 the question was "can this client run JavaScript", and a library with a JavaScript engine answered yes. Now the question is "does everything about this client agree with what it claims to be", and a Python process claiming to be Chrome fails on several independent signals at once — none of which a challenge solver touches.

Cloudflare has also added deliberately adversarial responses. Its AI Labyrinth serves crawlers coherent generated content indefinitely rather than blocking them, which means a scraper can appear to succeed while collecting nothing of value. We covered that pattern in honeypot traps.

Why Proxies Do Not Fix This

The part where we argue against our own product, because it is true.

Look at the detection list above and note what is on it: header composition and ordering, browser signals, machine-learned request features, JavaScript execution characteristics. The IP address appears nowhere in Cloudflare's own description of how the bot score is produced.

Address reputation is certainly one input to Cloudflare's overall decision, and a poor address will not help you. But it is one input among many, and it is not the one identifying a Python client as automated. A residential proxy in front of a requests session gives you a clean address attached to a client that still looks exactly like what it is.

The honest summary: if you are being flagged because your address is on a shared datacentre range with a bad history, better addresses help. If you are being flagged because your request does not look like the browser it claims to be, no address changes that — and we would rather say so than sell you bandwidth for it.

What to Do Instead

The genuinely useful section, in the order that solves the most problems.

Check for an official API. A large share of sites behind Cloudflare also publish one, precisely so that legitimate users have a sanctioned route. This is checked far less often than it should be, because the reflex is to search for a bypass rather than for documentation.

Check for a data feed or partner programme. Whole industries publish bulk data for downstream consumers. Ask.

Check what is available without the protected path. Sitemaps, RSS feeds, JSON-LD embedded in pages, public datasets, archives. It is common to find that the specific thing you wanted is published somewhere unprotected.

Ask the site. An email explaining who you are, what you need and at what volume resolves this more often than the discourse suggests. A site operator's objection is usually to unexplained load, not to you specifically. This is also the only route that produces access which keeps working.

Use a licensed data provider. For common data — company information, product catalogues, market data — someone sells it, and the price is frequently lower than the engineering time spent avoiding the purchase.

Consider whether you need less. A great deal of collection gathers far more than the question requires. A smaller, more specific ask is easier to satisfy by legitimate means and easier to justify when you ask.

And if you are running a legitimate automated client, the emerging route is identification rather than disguise. The industry is moving towards cryptographic agent authentication, per-agent access policies and in some cases paid access for automated traffic — a direction we described in our piece on DataDome. Being an agent a site can identify and choose to permit is the only approach that gets more reliable over time rather than less.

If You Have Existing Code Using It

Practical guidance for the situation many people are actually in: a working pipeline built on cloudscraper that has started failing.

First, establish what is actually happening. "It stopped working" covers several distinct failures with different responses. Print the status code and the first part of the body rather than only catching the exception:

import cloudscraper

scraper = cloudscraper.create_scraper()
r = scraper.get(url)
print(r.status_code, r.headers.get("content-type"))
print(r.text[:300])

A 403 with a Cloudflare block page means you were identified. A 200 with a challenge page means the challenge was not solved. A 200 with plausible but irrelevant content means you may be in a tarpit. A 503 with a Cloudflare interstitial means the old-style challenge is still in play and something else in your setup is wrong. Each points somewhere different.

Then check whether the site changed or the library did. Fetch the same URL with plain requests and with a real browser. If the browser works and both Python paths fail identically, the site has tightened its protection and no configuration of the library will help. If plain requests works, cloudscraper is adding a problem rather than solving one — which happens, and which is worth checking before assuming you need it.

Do not pin an older version hoping to recover behaviour. The failure is on the other side of the connection, not in the package. There is no earlier release that knows about a detection method introduced after it was written.

Remove it if it is no longer doing anything. A dependency that was solving a challenge which no longer appears is an unmaintained package in your supply chain for no benefit. Sites move on and off Cloudflare's more aggressive modes, and a pipeline built during an aggressive period may work fine without the library now. Test it.

And treat the failure as information about the project rather than a bug to fix. A collection pipeline that requires an unmaintained bypass library to function is one with a structural problem, and the time spent restoring it is time not spent finding the API, the feed, or the person to ask. In our experience the second search succeeds more often than the first.

Where Proxies Genuinely Belong

For completeness, since this is our business and there are real uses.

Distributing volume across addresses when you have optimised your rate and a single address is the constraint. This is a throughput problem, and it is the one proxies solve.

Seeing region-specific content, where appearing to be somewhere is the entire point of the exercise.

Getting past a network that filters a site, which is a problem at your end rather than the site's.

Ad verification and brand monitoring, checking your own spend from the regions you paid for.

None of these is a bypass. All of them are cases where the address is genuinely the variable, and in each the sensible starting point is datacentre bandwidth — ours from $0.14/GB — escalating to residential at $0.79/GB only where it is demonstrably needed. Figures from our pricing page, checked September 2026.

What we will not do is sell a plan on the implication that it defeats a machine-learning model examining header order. That is not what an IP address does.

People Also Ask

Does cloudscraper still work?

Against modern Cloudflare protection, generally not. The last PyPI release is from April 2023, and the library was designed for an era when the challenge was principally a JavaScript check. Current detection uses machine learning over request features, header-order analysis and JavaScript-based headless detection, none of which a challenge solver addresses.

Is cloudscraper still maintained?

The repository is not archived, but the last release was April 2023 and the most recent commits — from June 2025 — are administrative rather than functional. For a library whose value depends entirely on tracking a changing target, the release date is effectively the specification.

Why does cloudscraper return a 403?

Because Cloudflare identified the client through signals the library does not control. Header ordering, TLS handshake characteristics and machine-learned request features all point at a Python HTTP client regardless of whether a JavaScript challenge was solved.

Will a proxy make cloudscraper work?

No, unless address reputation is specifically the reason you were flagged. Cloudflare's own description of its bot score covers machine learning on request features, heuristics, JavaScript detections and header-order rules — none of which change when your address does.

What can I use instead of cloudscraper?

Look for an official API, a partner data feed, or the data published elsewhere without protection. Then consider asking the site directly, which resolves this more often than people expect and produces access that keeps working. Licensed data providers are frequently cheaper than the engineering time spent avoiding them.

Is bypassing Cloudflare legal?

Terms of service violations are contractual rather than criminal in most jurisdictions, and the realistic consequence is blocking. Legality depends on jurisdiction, the data involved and how it is used. A site that has deployed protection has stated a position, which is worth weighing regardless of the legal analysis. This is not legal advice.

Why do I get a 200 response with no useful content?

You may have reached a tarpit. Cloudflare's AI Labyrinth serves crawlers coherent, factually plausible generated content that is simply irrelevant to the site, rather than blocking them. Everything returns successfully while you collect nothing, which is by design.

Does using a headless browser work better?

It addresses more signals than a requests-based library, since a real browser produces real TLS and header characteristics. It also costs far more in bandwidth and compute, and Cloudflare's JavaScript detections specifically target headless browsers. It is a different trade-off rather than a solution, and the terms question is unchanged.

Wrapping Up

Cloudscraper solved a real problem well, and the problem it solved no longer exists in the form it was built for. The last functional release predates several generations of change on the other side, and the library's own README promises frequent updates that have not happened for over three years.

Understanding why is more useful than finding a replacement. The old question was whether a client could run JavaScript, and a library with a JavaScript engine could answer it. The current question is whether everything about a client agrees with what it claims to be — header order, TLS characteristics, browser signals, behaviour — and a Python HTTP session claiming to be Chrome fails on several of those simultaneously, no matter what it solves.

That is also why we will not sell you proxies as the fix. Cloudflare's own account of how its bot score is produced does not mention the client address at all. Better addresses help with address problems and with nothing else.

What does work is unglamorous and durable: find the API, find the feed, find the data published elsewhere, or ask. The last one in particular has a much higher success rate than the discourse suggests, and it is the only route that does not need revisiting every time somebody ships a detection update.

Cloudscraper in Python: What It Was and Why It Stopped Working | Geonode