Cloudflare "Even geduld" in Python: Waarom requests faalt

Cloudflare's 'Even geduld...' pagina is een JavaScript-uitdaging, en Python requests kan geen JavaScript uitvoeren. Hier is hoe je het kunt detecteren, waarom het servers harder raakt dan laptops, waarom cloudscraper-achtige trucs niet meer voldoende zijn, en wat er doorheen kwam in onze test van 29 september 2026.

'Even geduld...' is Cloudflare's uitdagingpagina. Het vraagt de client om JavaScript uit te voeren en te bewijzen dat het een browser is voordat de site antwoordt. Python requests kan geen JavaScript uitvoeren, en vanaf een datacenter server ziet zijn IP en TLS-handdruk er al geautomatiseerd uit. Wat er doorheen komt is een echte browser op een schoon IP, of een web unlocker die er een uitvoert.

Deze gids laat zien hoe je de uitdaging in Python kunt detecteren, waarom hetzelfde script slaagt op je laptop en faalt op je server, waarom cloudscraper-tijdperk trucs niet meer voldoende zijn, en wat er daadwerkelijk doorheen kwam toen we het testten op 29 september 2026. Dat omvat de site waar niets wat we probeerden voorbij 'Even geduld' kwam.

Wat de "Even geduld..." pagina eigenlijk is

Cloudflare noemt het een interstitial Challenge Page: een volledige pagina als poort tussen de bezoeker en de site terwijl Cloudflare beslist of de bezoeker geautomatiseerd is. Zijn documentatie over uitdagingpagina's beschrijft drie soorten. Een niet-interactieve uitdaging heeft alleen de browser nodig om de geïnjecteerde JavaScript uit te voeren. Een beheerde uitdaging laat Cloudflare het type uitdaging kiezen op basis van de signalen van het verzoek. Een interactieve uitdaging vraagt de bezoeker iets te doen. Wanneer de controle slaagt, gaat het oorspronkelijke verzoek door naar de site en krijgt de browser een cf_clearance cookie waarmee het de poort een tijdje kan overslaan.

Een Python HTTP-client komt nooit zover. Het downloadt de uitdagingpagina, heeft geen engine om het script uit te voeren, en geeft je de HTML van de poort in plaats van de pagina die je vroeg.

Waarom de uitdaging terugkomt als een 403, en hoe je het kunt detecteren

In onze test arriveerde elke uitdagingpagina met status 403, wat de reden is dat raise_for_status() 403 Client Error: Forbidden gooit en mensen zoeken naar 'cloudflare even geduld 403'. De status alleen kan een uitdaging niet onderscheiden van elke andere weigering. Het betrouwbare signaal is een header: Cloudflare documenteert dat een uitgedaagde reactie cf-mitigated: challenge draagt, ongeacht welke bron je hebt aangevraagd. Controleer dat eerst, dan de titel als fallback:

import re
import requests

URL = "https://www.glassdoor.com/Reviews/Google-Reviews-E9079.htm"
HEADERS = {
    "User-Agent": (
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
        "(KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36"
    ),
    "Accept-Language": "en-US,en;q=0.9",
}


def title_of(html: str) -> str:
    m = re.search(r"<title[^>]*>(.*?)</title>", html, re.I | re.S)
    return m.group(1).strip() if m else ""


def is_cloudflare_challenge(r: requests.Response) -> bool:
    if r.headers.get("cf-mitigated") == "challenge":      # documented by Cloudflare
        return True
    if "just a moment" in title_of(r.text).lower():
        return True
    return "enable javascript and cookies to continue" in r.text[:20000].lower()


r = requests.get(URL, headers=HEADERS, timeout=30)
print(r.status_code, is_cloudflare_challenge(r), title_of(r.text))
# 29 Sep 2026, plain request through a residential proxy (US exit):
# 403, body asking to 'Enable JavaScript and cookies to continue'

Herhaal een uitgedaagd verzoek niet in een strakke lus met dezelfde client. Elke herhaling haalt dezelfde poort op, en sommige sites beantwoorden herhaalde mislukkingen met strengere regels. Zo raken scrapers vast in een 'Even geduld' lus.

"Schakel JavaScript en cookies in om door te gaan" en "uw browser ondersteunt geen JavaScript"

Deze strings zijn de fallback-tekst van een uitdagingpagina, getoond aan clients die zijn script niet uitvoeren. Wanneer Python requests je een van hen laat zien, klaagt de site niet over je headers. Het vertelt je letterlijk dat het een JavaScript-engine en een cookiejar nodig heeft die bewaart wat het script instelt.

Dat is precies wat onze eenvoudige residentiële run ontving van Indeed en Glassdoor: een 403 met 'Schakel JavaScript en cookies in om door te gaan', van een schoon thuis-IP. Het toevoegen van een Chrome User-Agent, een Accept-Language header of een Referer verandert niets, omdat de pagina ze niet leest om te beslissen. Het wacht op de uitvoering van het script.

Waarom je scraper lokaal werkt maar door Cloudflare op een server wordt geblokkeerd

Dit is de meest voorkomende versie van de klacht: het script werkt op een laptop, dan krijgt het 'Even geduld' zodra het op een cloud VM draait. Twee dingen veranderen tussen die machines.

De residentiële kolom van onze test toont de limiet van alleen het IP repareren. Zillow en Leboncoin leverden de echte pagina aan een eenvoudige aanvraag via een residentiële proxy. Indeed en Glassdoor antwoordden nog steeds met de JavaScript-uitdaging. Je laptop kan dezelfde muur raken op een strengere site. Het raakt het gewoon minder vaak.

Waarom een Python scraper Cloudflare passeert vanaf een laptop en de Even geduld uitdaging krijgt vanaf een cloudserver: thuis IP versus hosting IP, dezelfde Python TLS-vingerafdruk, geen JavaScript-engine in beide gevallen
Zelfde script, twee machines. Het IP verandert; de Python TLS-handdruk en de ontbrekende JavaScript-engine niet.

Waarom cloudscraper-tijdperk trucs niet meer werken

cloudscraper werd gebouwd voor Cloudflare's oudere 'I'm Under Attack' pagina. Die pagina controleerde voornamelijk of de client een JavaScript-berekening kon uitvoeren, dus de bibliotheek haalde de uitdaging op, loste het script op in een ingebedde interpreter, stuurde het antwoord terug en bewaarde de cookie, allemaal bovenop requests. Lange tijd was dat genoeg, en het is de reden waarom 'cloudscraper alternatief' nu een zoekopdracht is die mensen maken.

Verschillende dingen zijn sindsdien veranderd, en ze zijn niet afhankelijk van een specifieke bibliotheekversie:

Vanaf 29 september 2026 was de laatste push van de cloudscraper repository in juni 2025. Dat is geen oordeel over een specifieke site, en we hebben het niet gebenchmarkt voor dit artikel. Het betekent wel dat je het moet testen tegen je eigen doelen in plaats van aan te nemen dat het werkt. De alternatieven lossen elk een deel van het probleem op. curl_cffi reproduceert een browser TLS-handdruk maar voert geen JavaScript uit. Playwright of een andere echte browser voert de uitdaging uit maar heeft nog steeds een schoon IP nodig, en is zwaar om op grote schaal te opereren. De unlocker combineert de twee en vertelt je wanneer geen van beide werkte.

Wat er doorheen komt: het web unlocker pad

De QuantumProxies.io Web Unlocker behandelt een GET in fasen. Eerst, tot drie TLS-pogingen, elk op een verse residentiële exit onder een andere browser vingerafdruk. Als elke poging uitgedaagd terugkomt, escaleert het naar een headless browser die de uitdaging uitvoert. Als de pagina daarna nog steeds geblokkeerd is, krijg je een foutstatus met x-qp-unlocker-blocked en een blokklasse, nooit een uitdagingpagina vermomd als een 200. Vanuit Python is het een proxy-instelling:

import os
import time
import requests
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

user = os.environ["QP_UNLOCK_USER"] + "-country-us"          # unlock-XXXXXXXX-country-us
PROXY = f"http://{user}:{os.environ['QP_UNLOCK_PASSWORD']}@unlock.quantumproxies.io:9000"

s = requests.Session()
s.proxies = {"http": PROXY, "https": PROXY}
s.verify = False                     # or the unlocker CA file from /api/v1/scraper/unlock/ca
s.headers["x-qp-session"] = "glassdoor-01"   # same value on every call: same exit, reusable clearance

for attempt in (1, 2):               # same page twice here; in practice, the next page
    t0 = time.monotonic()
    r = s.get(URL, timeout=120)
    print(attempt, r.status_code, f"{time.monotonic() - t0:.1f}s",
          "rendered:", r.headers.get("x-qp-unlocker-rendered"),
          "clearance:", r.headers.get("x-qp-clearance"),
          "block:", r.headers.get("x-qp-block-class"))

De x-qp-* headers worden gelezen door de unlocker en nooit doorgestuurd naar de site. Als je liever helemaal niet met het certificaat te maken hebt, neemt het REST-eindpunt POST https://app.quantumproxies.io/api/v1/scraper/unlock de URL in een JSON-body met je API-sleutel en retourneert blocked, blockClass en vendor in de reactie. Onze web unlocker API-tutorial loopt door beide heen.

Gemeten: twee Cloudflare-achtige muren die passeerden, één die dat niet deed

Gemeten op 29 september 2026. Eenvoudige requests waren curl met een Chrome User-Agent, vanaf een datacenter server in Frankfurt en via een residentiële proxy met een Amerikaanse exit. De unlocker gebruikte de residentiële tier met een Amerikaanse exit. Tijden zijn wandklok voor één verzoek.

SiteEenvoudig, datacenter serverEenvoudig, residentiële proxyWeb Unlocker
Glassdoor (bedrijf beoordelingen)403, 'Beveiligings' pagina403, 'Schakel JavaScript en cookies in om door te gaan'200, 2 pogingen + headless browser, 17,2 s
Indeed (baan zoeken)403, 'Beveiligingscontrole' pagina403, 'Schakel JavaScript en cookies in om door te gaan'200, 1 poging, geen browser, 2,6 s
StockX (productpagina)403403403 'Even geduld...', x-qp-block-class js_challenge, vendor cloudflare, 47,8 s
DoorDash (stadspagina)403403403, x-qp-block-class ip_reputation, vendor cloudflare

Glassdoor is het volledige pad. Twee TLS-pogingen werden uitgedaagd, daarna voerde de headless browser de uitdaging uit en retourneerde de beoordelingspagina. Indeed is de interessante: de uitdaging die het eenvoudige residentiële verzoek ontving verscheen nooit voor de eerste poging van de unlocker. Een browser TLS-vingerafdruk op een verse residentiële exit was genoeg, zonder een browser.

StockX is de eerlijke mislukking. De unlocker escaleerde, besteedde 47,8 seconden, en de pagina was nog steeds 'Even geduld...'. Het kwam terug als een 403 met x-qp-block-class: js_challenge en x-qp-vendor: cloudflare, niet als een 200 die je parser zou hebben geprobeerd te lezen. DoorDash, ook achter Cloudflare, werd geweigerd op het IP (ip_reputation) in plaats van uitgedaagd. Sommige Cloudflare-configuraties openen niet voor een van de tools in dit artikel, en het is beter om dat te weten van een header dan van een lege dataset.

Omzeil JavaScript-uitdagingen met de Web Unlocker

Het hergebruiken van de clearance: waarom het tweede verzoek snel is

De browser-escalatie is het trage deel, en je wilt er niet voor betalen bij elke pagina. Wanneer de headless browser een uitdaging passeert, verdient het een clearance. Stuur dezelfde x-qp-session waarde, of houd dezelfde -session-&lt;id&gt; in de proxy gebruikersnaam, bij de volgende verzoeken en ze vertrekken van dezelfde exit, waarbij die clearance wordt hergebruikt in plaats van de browser opnieuw te draaien. De x-qp-clearance header vertelt je wat er bij elke oproep gebeurde: minted wanneer een nieuwe clearance werd verdiend, hit wanneer een opgeslagen werd hergebruikt, miss wanneer er niets was om te hergebruiken.

In een Glassdoor-test op 29 september 2026, met de sessie vastgepind in de proxy gebruikersnaam en twee afzonderlijke verbindingen, ging het eerste verzoek door de browser in 14,0 seconden (minted) en het tweede kwam terug in 1,4 seconden (hit). Het vastpinnen is belangrijk vanwege hoe Cloudflare clearance bindt: het is gekoppeld aan de bezoeker en het apparaat dat het verdiende, en het blijft geldig voor de duur die de site configureert tenzij Cloudflare besluit dat de sessie verdacht lijkt. Verander de exit of de vingerafdruk en je bent weer een nieuwe bezoeker.

Tijdlijn van twee verzoeken in één vastgepinde unlocker sessie: de eerste escaleert naar een headless browser en mint een Cloudflare clearance in 14,0 seconden, de tweede hergebruikt het en keert terug in 1,4 seconden
Eerste verzoek betaalt voor de browser; latere verzoeken in dezelfde vastgepinde sessie hergebruiken de clearance.

Wanneer eenvoudige requests nog steeds prima is op een Cloudflare-site

Veel sites draaien achter Cloudflare alleen als een CDN, of met botregels die gewoon verkeer doorlaten, en eenvoudige requests werkt op hen. 'Op Cloudflare' zijn is geen reden om naar een browser te grijpen. Het signaal is de reactie. Als er geen cf-mitigated: challenge header is, geen 'Even geduld' titel en geen 403, houd het eenvoudige verzoek, en escaleer alleen de URL's die daadwerkelijk worden uitgedaagd. De plain-first helper in onze tutorial doet precies dat.

Twee naburige problemen hebben hun eigen gidsen. Een pagina die 'Error 1020 Access denied' zegt is een firewallregel die je weigert, geen uitdaging, en geen hoeveelheid JavaScript lost het op; zie wat Cloudflare fout 1020 triggert en wat het oplost. Voor het bredere beeld van Cloudflare's verdedigingen buiten Python, lees hoe Cloudflare-uitdagingen in 2026 te omzeilen. Als de pagina achter de muur Glassdoor is, behandelt onze gids voor het scrapen van Glassdoor salarissen en beoordelingen de datakant.

Veelgestelde vragen

Waarom werkt mijn scraper lokaal maar wordt deze geblokkeerd door Cloudflare in de cloud?

Omdat het IP verandert. Thuis vertrekt je script vanaf een residentieel ISP-adres; op een cloud VM vertrekt het vanuit een hostingbereik dat botverdedigingen wantrouwen bij het zien. De Python TLS-handdruk is hetzelfde op beide, en op een strengere site wordt het zelfs vanaf thuis uitgedaagd. In onze test slaagde een residentieel IP alleen niet voor Indeed of Glassdoor.

Waarom retourneert Cloudflare's "Even geduld" pagina een 403?

De uitdagingpagina wordt geserveerd in plaats van de pagina die je vroeg, en in onze test kwam het met status 403, dus requests geeft '403 Client Error: Forbidden'. De status is niet specifiek voor uitdagingen. Controleer de cf-mitigated response header, die Cloudflare documenteert als ingesteld op challenge bij elke Challenge Page-reactie, of de 'Even geduld' titel.

Werkt cloudscraper nog steeds, en wat is een goed alternatief?

Het kan nog steeds werken op sites met milde instellingen, dus test het tegen je doelen. Het draait op Python's TLS-stack en lost scripts op in een interpreter, terwijl huidige uitdagingen ook naar de handdruk en de browseromgeving kijken. Alternatieven: curl_cffi voor een browserhanddruk, een echte browser voor de JavaScript, of een web unlocker die beide doet.

Kan Python requests een Cloudflare-uitdaging op zichzelf passeren?

Nee. requests voert geen JavaScript uit, dus het kan geen uitdaging voltooien die afhankelijk is van het uitvoeren van het script van de pagina. Het kan pagina's ophalen van Cloudflare-sites die je niet uitdagen. Zodra cf-mitigated: challenge verschijnt, heb je een echte browser nodig, direct of via een service die er een uitvoert, en idealiter een schoon residentieel IP.

Kan de web unlocker Cloudflare Turnstile of andere captchas oplossen?

Niet-interactieve JavaScript-uitdagingen worden beantwoord door de headless browser-escalatie. Interactieve uitdagingen die een menselijke actie vereisen, zoals een selectievakje, schuifregelaar, druk-en-houd of afbeeldingsraster, worden niet opgelost. Het verzoek mislukt in plaats van de uitdaging als een 200 te retourneren, en het REST-eindpunt labelt het met de blokklasse captcha en de leverancier, zodat je code kan beslissen of je de URL wilt overslaan, vertragen of later proberen.

Hoe lang duurt een Cloudflare clearance?

Zolang de site het configureert. Cloudflare noemt de instelling Challenge Passage, en clearance kan vroeg eindigen als Cloudflare besluit dat de sessie verdacht lijkt. De cf_clearance cookie is gekoppeld aan de bezoeker en het apparaat dat het verdiende, dus het helpt alleen als latere verzoeken dezelfde exit en vingerafdruk behouden, wat is wat het vastpinnen van x-qp-session doet.

De korte versie: 'Even geduld...' vraagt om een browser, dus geen enkele headertruc in requests zal het tevredenstellen. Detecteer het met cf-mitigated, houd eenvoudige requests voor alles wat niet wordt uitgedaagd, stuur de uitgedaagde URL's door iets dat een echte browser uitvoert vanaf een schoon IP, en pin een sessie zodat je voor die browser één keer betaalt in plaats van bij elke pagina.

Probeer de Web Unlocker op residentiële exits