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.
- Het is een uitdaging, geen fout. Cloudflare markeert uitgedaagde reacties met de header
cf-mitigated: challenge. In onze test kwamen ze aan als HTTP 403. - Headers lossen het niet op. 'Schakel JavaScript en cookies in om door te gaan' betekent dat de pagina een JavaScript-engine wil. Geen enkele User-Agent string levert er een.
- Server versus laptop is meestal IP-reputatie plus de TLS-vingerafdruk. Een residentieel IP alleen slaagde niet voor Indeed of Glassdoor in onze test.
- Wat slaagde: de Web Unlocker kreeg Glassdoor (na een headless browser, 17,2 s) en Indeed (eerste poging, 2,6 s). StockX gaf nog steeds 'Even geduld...' terug en werd gerapporteerd als
js_challenge. - Pin een sessie. Het hergebruiken van de browser's clearance verkortte een tweede Glassdoor-verzoek van 14,0 s naar 1,4 s in onze test.
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.
- Het IP. Op je laptop vertrekt het script vanaf een thuis-ISP-adres. Op een VM vertrekt het vanuit een hostingprovider's bereik, wat botverdedigingen als waarschijnlijk geautomatiseerd scoren voordat ze iets anders lezen. Onze datacenter server in Frankfurt werd geweigerd door Glassdoor, Indeed, Zillow en Leboncoin, onder anderen.
- De TLS-vingerafdruk. Python's handdruk ziet eruit als Python op beide machines, maar op een thuis-IP kan een site het tolereren en op een hosting-IP zal het zelden dat doen. Onze uitleg over curl_cffi vs requests laat zien hoeveel van de handdruk een bibliotheek beheert.
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 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:
- De handdruk zegt nog steeds Python. Een bibliotheek gebouwd op requests maakt verbinding via Python's TLS-stack, dus de ClientHello komt niet overeen met de browser die zijn User-Agent beweert te zijn. Die mismatch is zichtbaar voordat er JavaScript wordt uitgevoerd.
- De uitdaging is niet langer alleen rekenkundig. Beheerde uitdagingen kiezen de controle uit de signalen van het verzoek, en Cloudflare's JavaScript-detecties lezen de browseromgeving. Een interpreter die een script evalueert is geen browser die een pagina weergeeft.
- Clearance is gebonden aan de client. Cloudflare's clearance documentatie zegt dat een cf_clearance cookie is gekoppeld aan de bezoeker en het apparaat waaraan het is uitgegeven, om hergebruik tussen machines te voorkomen. Er een kopiëren van je browser naar een script op een andere machine is ontworpen om te falen.
- Het IP is nog steeds van jou. Het oplossen van de pagina verandert een hosting-bereik IP niet, en sommige sites weigeren die voordat er een uitdaging wordt geserveerd.
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.
| Site | Eenvoudig, datacenter server | Eenvoudig, residentiële proxy | Web Unlocker |
|---|---|---|---|
| Glassdoor (bedrijf beoordelingen) | 403, 'Beveiligings' pagina | 403, 'Schakel JavaScript en cookies in om door te gaan' | 200, 2 pogingen + headless browser, 17,2 s |
| Indeed (baan zoeken) | 403, 'Beveiligingscontrole' pagina | 403, 'Schakel JavaScript en cookies in om door te gaan' | 200, 1 poging, geen browser, 2,6 s |
| StockX (productpagina) | 403 | 403 | 403 'Even geduld...', x-qp-block-class js_challenge, vendor cloudflare, 47,8 s |
| DoorDash (stadspagina) | 403 | 403 | 403, 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-<id> 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.

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.