Cloudflare "Just a Moment" in Python: Perché requests Fallisce

La pagina 'Just a moment...' di Cloudflare è una sfida JavaScript, e Python requests non può eseguire JavaScript. Ecco come rilevarla, perché colpisce i server più duramente dei laptop, perché i trucchi in stile cloudscraper non sono più sufficienti, e cosa è passato nel nostro test del 29 settembre 2026.

'Just a moment...' è la pagina di sfida di Cloudflare. Chiede al client di eseguire JavaScript e dimostrare di essere un browser prima che il sito risponda. Python requests non può eseguire JavaScript, e da un server di datacenter il suo IP e la stretta di mano TLS appaiono già automatizzati. Ciò che passa è un vero browser su un IP pulito, o un web unlocker che ne esegue uno.

Questa guida mostra come rilevare la sfida in Python, perché lo stesso script passa sul tuo laptop e fallisce sul tuo server, perché i trucchi dell'era cloudscraper non sono più sufficienti, e cosa è effettivamente passato quando lo abbiamo testato il 29 settembre 2026. Questo include il sito dove nulla di ciò che abbiamo provato è passato oltre 'Just a moment'.

Cosa è realmente la pagina "Just a moment..."

Cloudflare la chiama una Challenge Page interstiziale: un cancello a pagina intera tra il visitatore e il sito mentre Cloudflare decide se il visitatore è automatizzato. La sua documentazione sulle challenge pages descrive tre tipi. Una sfida non interattiva richiede solo che il browser esegua il JavaScript iniettato. Una sfida gestita consente a Cloudflare di scegliere il tipo di sfida dai segnali della richiesta. Una sfida interattiva chiede al visitatore di fare qualcosa. Quando il controllo passa, la richiesta originale continua verso il sito e il browser riceve un cookie cf_clearance che gli consente di saltare il cancello per un po'.

Un client HTTP Python non arriva mai così lontano. Scarica la pagina di sfida, non ha un motore per eseguire lo script, e ti consegna l'HTML del cancello invece della pagina che hai richiesto.

Perché la sfida torna come un 403, e come rilevarla

Nel nostro test, ogni pagina di sfida è arrivata con stato 403, ed è per questo che raise_for_status() lancia 403 Client Error: Forbidden e le persone cercano 'cloudflare just a moment 403'. Lo stato da solo non può distinguere una sfida da qualsiasi altro rifiuto, però. Il segnale affidabile è un'intestazione: Cloudflare documenta che una risposta sfidata porta cf-mitigated: challenge, qualunque risorsa tu abbia richiesto. Controlla prima quello, poi il titolo come ripiego:

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'

Non riprovare una richiesta sfidata in un ciclo stretto con lo stesso client. Ogni ripetizione recupera lo stesso cancello, e alcuni siti rispondono a fallimenti ripetuti con regole più severe. È così che gli scraper finiscono bloccati in un loop 'Just a moment'.

"Enable JavaScript and cookies to continue" e "your browser does not support JavaScript"

Queste stringhe sono il testo di ripiego di una pagina di sfida, mostrato ai client che non eseguono il suo script. Quando Python requests te ne mostra uno, il sito non si sta lamentando delle tue intestazioni. Ti sta dicendo, letteralmente, che ha bisogno di un motore JavaScript e di un contenitore di cookie che conservi ciò che lo script imposta.

È esattamente ciò che la nostra esecuzione residenziale semplice ha ricevuto da Indeed e Glassdoor: un 403 con 'Enable JavaScript and cookies to continue', da un IP domestico pulito. Aggiungere un User-Agent di Chrome, un'intestazione Accept-Language o un Referer non cambia nulla, perché la pagina non li sta leggendo per decidere. Sta aspettando che lo script venga eseguito.

Perché il tuo scraper funziona localmente ma viene bloccato da Cloudflare su un server

Questa è la versione più comune del reclamo: lo script funziona su un laptop, poi riceve 'Just a moment' non appena viene eseguito su una VM cloud. Due cose cambiano tra quelle macchine.

La colonna residenziale del nostro test mostra il limite di correggere solo l'IP. Zillow e Leboncoin hanno servito la vera pagina a una richiesta semplice tramite un proxy residenziale. Indeed e Glassdoor hanno ancora risposto con la sfida JavaScript. Il tuo laptop può colpire lo stesso muro su un sito più severo. Semplicemente lo colpisce meno spesso.

Perché uno scraper Python passa Cloudflare da un laptop e riceve la sfida Just a moment da un server cloud: IP domestico contro IP di hosting, stessa impronta digitale TLS Python, nessun motore JavaScript in entrambi i casi
Stesso script, due macchine. L'IP cambia; la stretta di mano TLS Python e il motore JavaScript mancante no.

Perché i trucchi dell'era cloudscraper smettono di funzionare

cloudscraper è stato costruito per la vecchia pagina 'I'm Under Attack' di Cloudflare. Quella pagina controllava principalmente se il client poteva eseguire un calcolo JavaScript, quindi la libreria recuperava la sfida, risolveva lo script in un interprete incorporato, inviava la risposta indietro e conservava il cookie, tutto sopra requests. Per molto tempo è stato sufficiente, ed è il motivo per cui 'alternativa a cloudscraper' è ora una ricerca che le persone fanno.

Diverse cose si sono mosse da allora, e non dipendono da una qualsiasi versione della libreria:

A partire dal 29 settembre 2026, l'ultimo push del repository cloudscraper è stato a giugno 2025. Questo non è un verdetto su nessun sito particolare, e non lo abbiamo valutato per questo articolo. Significa che dovresti testarlo contro i tuoi obiettivi piuttosto che presumere che funzioni. Le alternative risolvono ciascuna parte del problema. curl_cffi riproduce una stretta di mano TLS del browser ma non esegue JavaScript. Playwright o un altro vero browser esegue la sfida ma ha ancora bisogno di un IP pulito, ed è pesante da operare in volume. L'unlocker combina i due e ti dice quando nessuno dei due ha funzionato.

Cosa passa: il percorso del web unlocker

Il Web Unlocker di QuantumProxies.io gestisce un GET in fasi. Prima, fino a tre tentativi TLS, ciascuno su un'uscita residenziale fresca sotto un'impronta digitale del browser diversa. Se ogni tentativo torna sfidato, si intensifica a un browser headless che esegue la sfida. Se la pagina è ancora bloccata dopo, ottieni uno stato di errore con x-qp-unlocker-blocked e una classe di blocco, mai una pagina di sfida travestita da 200. Da Python è un'impostazione proxy:

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"))

Le intestazioni x-qp-* sono lette dall'unlocker e mai inoltrate al sito. Se preferisci non occuparti affatto del certificato, l'endpoint REST POST https://app.quantumproxies.io/api/v1/scraper/unlock prende l'URL in un corpo JSON con la tua chiave API e restituisce blocked, blockClass e vendor nella risposta. Il nostro tutorial sull'API del web unlocker guida attraverso entrambi.

Misurato: due muri in stile Cloudflare che sono passati, uno che non lo ha fatto

Misurato il 29 settembre 2026. Le richieste semplici erano curl con un User-Agent di Chrome, da un server di datacenter a Francoforte e tramite un proxy residenziale con un'uscita negli Stati Uniti. L'unlocker ha utilizzato il livello residenziale con un'uscita negli Stati Uniti. I tempi sono a orologio per una richiesta.

SitoSemplice, server di datacenterSemplice, proxy residenzialeWeb Unlocker
Glassdoor (recensioni aziendali)403, pagina 'Sicurezza'403, 'Enable JavaScript and cookies to continue'200, 2 tentativi + browser headless, 17,2 s
Indeed (ricerca lavoro)403, pagina 'Security Check'403, 'Enable JavaScript and cookies to continue'200, 1 tentativo, nessun browser, 2,6 s
StockX (pagina prodotto)403403403 'Just a moment...', x-qp-block-class js_challenge, vendor cloudflare, 47,8 s
DoorDash (pagina città)403403403, x-qp-block-class ip_reputation, vendor cloudflare

Glassdoor è il percorso completo. Due tentativi TLS sono stati sfidati, poi il browser headless ha eseguito la sfida e ha restituito la pagina delle recensioni. Indeed è quello interessante: la sfida che la richiesta residenziale semplice ha ricevuto non è mai apparsa per il primo tentativo dell'unlocker. Un'impronta digitale TLS del browser su un'uscita residenziale fresca è stata sufficiente, senza un browser.

StockX è il fallimento onesto. L'unlocker si è intensificato, ha impiegato 47,8 secondi, e la pagina era ancora 'Just a moment...'. È tornata come un 403 con x-qp-block-class: js_challenge e x-qp-vendor: cloudflare, non come un 200 che il tuo parser avrebbe provato a leggere. DoorDash, anch'esso dietro Cloudflare, è stato rifiutato sull'IP (ip_reputation) piuttosto che sfidato. Alcune configurazioni di Cloudflare non si aprono per nessuno degli strumenti in questo articolo, ed è meglio saperlo da un'intestazione piuttosto che da un dataset vuoto.

Supera le sfide JavaScript con il Web Unlocker

Riutilizzare la clearance: perché la seconda richiesta è veloce

L'escalation del browser è la parte lenta, e non vuoi pagarla su ogni pagina. Quando il browser headless supera una sfida, guadagna una clearance. Invia lo stesso valore x-qp-session, o mantieni lo stesso -session-&lt;id&gt; nel nome utente del proxy, sulle richieste successive e partono dalla stessa uscita, riutilizzando quella clearance invece di eseguire di nuovo il browser. L'intestazione x-qp-clearance ti dice cosa è successo su ogni chiamata: minted quando è stata guadagnata una nuova clearance, hit quando ne è stata riutilizzata una memorizzata, miss quando non c'era nulla da riutilizzare.

In un test su Glassdoor il 29 settembre 2026, con la sessione fissata nel nome utente del proxy e due connessioni separate, la prima richiesta è passata attraverso il browser in 14,0 secondi (minted) e la seconda è tornata in 1,4 secondi (hit). La fissazione è importante a causa di come Cloudflare lega la clearance: è legata al visitatore e al dispositivo che l'ha guadagnata, e rimane valida per la durata configurata dal sito a meno che Cloudflare decida che la sessione sembra sospetta. Cambia l'uscita o l'impronta digitale e sei di nuovo un nuovo visitatore.

Cronologia di due richieste in una sessione unlocker fissata: la prima si intensifica a un browser headless e conia una clearance Cloudflare in 14,0 secondi, la seconda la riutilizza e ritorna in 1,4 secondi
La prima richiesta paga per il browser; le richieste successive nella stessa sessione fissata riutilizzano la clearance.

Quando le richieste semplici vanno ancora bene su un sito Cloudflare

Molti siti funzionano dietro Cloudflare solo come CDN, o con regole bot che lasciano passare il traffico ordinario, e le richieste semplici funzionano su di essi. Essere 'su Cloudflare' non è un motivo per ricorrere a un browser. Il segnale è la risposta. Se non c'è l'intestazione cf-mitigated: challenge, nessun titolo 'Just a moment' e nessun 403, mantieni la richiesta semplice, ed esegui l'escalation solo sugli URL che vengono effettivamente sfidati. Il nostro helper plain-first nel tutorial fa esattamente questo.

Due problemi vicini hanno le loro guide. Una pagina che dice 'Error 1020 Access denied' è una regola del firewall che ti rifiuta, non una sfida, e nessuna quantità di JavaScript la risolve; vedi cosa innesca l'errore 1020 di Cloudflare e cosa lo risolve. Per il quadro più ampio delle difese di Cloudflare oltre Python, leggi come bypassare le sfide di Cloudflare nel 2026. Se la pagina dietro il muro è Glassdoor, la nostra guida per estrarre stipendi e recensioni da Glassdoor copre il lato dati.

Domande frequenti

Perché il mio scraper funziona localmente ma viene bloccato da Cloudflare nel cloud?

Perché l'IP cambia. A casa il tuo script parte da un indirizzo ISP residenziale; su una VM cloud parte da un intervallo di hosting che le difese anti-bot diffidano a prima vista. La stretta di mano TLS di Python è la stessa su entrambi, e su un sito più severo viene sfidata anche da casa. Nel nostro test, un IP residenziale da solo non è passato su Indeed o Glassdoor.

Perché la pagina "Just a moment" di Cloudflare restituisce un 403?

La pagina di sfida viene servita al posto della pagina che hai richiesto, e nel nostro test è arrivata con stato 403, quindi requests solleva '403 Client Error: Forbidden'. Lo stato non è specifico per le sfide. Controlla l'intestazione di risposta cf-mitigated, che Cloudflare documenta come impostata su challenge su ogni risposta di Challenge Page, o il titolo 'Just a moment'.

Cloudscraper funziona ancora, e qual è una buona alternativa?

Può ancora funzionare su siti con impostazioni indulgenti, quindi testalo contro i tuoi obiettivi. Funziona sullo stack TLS di Python e risolve gli script in un interprete, mentre le sfide attuali guardano anche alla stretta di mano e all'ambiente del browser. Alternative: curl_cffi per una stretta di mano del browser, un vero browser per il JavaScript, o un web unlocker che fa entrambi.

Python requests può superare una sfida Cloudflare da solo?

No. requests non esegue JavaScript, quindi non può completare una sfida che dipende dall'esecuzione dello script della pagina. Può recuperare pagine da siti Cloudflare che non ti stanno sfidando. Una volta che cf-mitigated: challenge appare, hai bisogno di un vero browser, direttamente o tramite un servizio che ne esegue uno, e idealmente un IP residenziale pulito.

Il web unlocker può risolvere Cloudflare Turnstile o altri captcha?

Le sfide JavaScript non interattive vengono risolte dall'escalation del browser headless. Le sfide interattive che richiedono un'azione umana, come una casella di controllo, uno slider, un premi-e-tieni o una griglia di immagini, non vengono risolte. La richiesta fallisce invece di restituire la sfida come un 200, e l'endpoint REST la etichetta con la classe di blocco captcha e il vendor, così il tuo codice può decidere se saltare l'URL, rallentare o riprovare più tardi.

Quanto dura una clearance Cloudflare?

Per tutto il tempo che il sito la configura. Cloudflare chiama l'impostazione Challenge Passage, e la clearance può terminare in anticipo se Cloudflare decide che la sessione sembra sospetta. Il cookie cf_clearance è legato al visitatore e al dispositivo che l'ha guadagnato, quindi aiuta solo se le richieste successive mantengono la stessa uscita e impronta digitale, che è ciò che fa il pinning di x-qp-session.

La versione breve: 'Just a moment...' chiede un browser, quindi nessun trucco di intestazione in requests lo soddisferà. Rilevalo con cf-mitigated, mantieni le richieste semplici per tutto ciò che non è sfidato, invia gli URL sfidati attraverso qualcosa che esegue un vero browser da un IP pulito, e fissa una sessione così paghi per quel browser una volta piuttosto che su ogni pagina.

Prova il Web Unlocker su uscite residenziali