Come risolvere un PopularCaptcha in Python (esempio funzionante, 2026)
Se il tuo script Python si è imbattuto in un PopularCaptcha, non ti servono una farm di browser né un modello tuo. Ti servono la sitekey della pagina, una richiesta POST e il token che ne torna indietro.
Questa guida ti porta da zero a un token funzionante in circa cinque minuti: ottieni una chiave API, trova la sitekey, richiedi il token, invialo al modulo e gestisci i casi di errore che emergono quando uno script gira senza supervisione. I solve falliti sono gratuiti, quindi un nuovo tentativo ti costa solo tempo.
Scarnox risolve oggi PopularCaptcha, in modalità proxyless o con il tuo proxy. Gli altri tipi di captcha come reCAPTCHA, Cloudflare Turnstile e AWS WAF sono in arrivo, quindi ogni esempio qui usa PopularCaptcha. La panoramica dei tipi di captcha spiega come gli altri si differenziano.
1. Ottieni una chiave API
Crea un account e inizia con il credito di prova gratuito, senza carta. La tua chiave API si trova nella dashboard. Tienila fuori dal codice sorgente e leggila da una variabile d'ambiente:
export SCARNOX_KEY="scarnox_YOURAPIKEY"
2. Trova la sitekey
Apri la pagina con il captcha, apri DevTools e cerca data-sitekey nel pannello Elements. Le sitekey di PopularCaptcha sono UUID:
<div class="h-captcha" data-sitekey="10000000-ffff-ffff-ffff-000000000001"></div>
Non trovi data-sitekey nell'HTML? Il widget probabilmente viene renderizzato da JavaScript. Controlla nella scheda Network la richiesta di configurazione del widget: il suo parametro di query sitekey è quello che ti serve. Altri modi per trovarla coprono l'URL dell'iframe e i widget invisibili.
Invia come site_url l'URL della pagina che mostra il widget. L'host conta di più, ma l'URL completo della pagina è la scelta sicura.
3. Richiedi un token
import os
import requests
API_URL = "https://api.scarnox.com/api/tasks/create"
API_KEY = os.environ["SCARNOX_KEY"]
def solve_captcha(sitekey: str, page_url: str) -> str:
r = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"captcha_type": "PopularCaptchaTaskProxyless",
"site_key": sitekey,
"site_url": page_url,
},
timeout=185, # la chiamata si blocca finché il token è pronto
)
data = r.json()
if data.get("errorId") != 0:
raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
return data["solution"]["token"]
if __name__ == "__main__":
token = solve_captcha("10000000-ffff-ffff-ffff-000000000001", "https://example.com/signup")
print(token[:40], "...")
È l'intera integrazione. Non c'è nessun ciclo di polling né una seconda chiamata "get result". La richiesta restituisce il risultato quando il token è pronto, quindi l'unica impostazione che conta è un timeout abbastanza lungo da coprire una risoluzione lenta. Usa circa 185 secondi.
Una risposta riuscita ha errorId impostato a 0, con il token in solution.token. Qualsiasi altro errorId significa che la risoluzione è fallita, e la risposta contiene un errorCode e una errorDescription che spiegano il motivo.
4. Invia il token
Il token va dove il sito si aspetta la risposta del captcha. Per PopularCaptcha è quasi sempre un campo del modulo chiamato h-captcha-response. Molti siti accettano anche g-recaptcha-response, quindi inviali entrambi:
import requests
def sign_up(session: requests.Session, form_url: str, email: str, sitekey: str) -> requests.Response:
token = solve_captcha(sitekey, form_url)
return session.post(form_url, data={
"email": email,
"h-captcha-response": token,
"g-recaptcha-response": token,
}, timeout=30)
Due dettagli contano qui. I siti reali di solito verificano anche i cookie di sessione del caricamento della pagina, quindi carica il modulo con lo stesso requests.Session prima di inviare il POST. E invia alla action del modulo, che non sempre è l'URL della pagina.
Risolvi subito prima di inviare. Il token scade entro circa due minuti, quindi non recuperarlo all'inizio di un lavoro lungo e non tenerlo in memoria. Se il sito rifiuta il token, apri il modulo in DevTools e verifica i nomi esatti dei campi nascosti.
5. Gestisci gli errori
I solve falliti sono gratuiti, quindi un nuovo tentativo costa solo tempo. Alcuni errori però non riusciranno mai al nuovo tentativo, quindi non fare cicli alla cieca. Controlla errorId ogni volta, registra errorCode e errorDescription, e ritenta solo gli errori transitori.
Gli errori di rete richiedono una gestione a parte, perché requests lancia un'eccezione prima che esista qualsiasi risposta:
import requests
try:
token = solve_captcha(sitekey, page_url)
except requests.RequestException as exc:
print("network problem, retry later:", exc)
except RuntimeError as exc:
print("solve rejected:", exc)
La guida alla gestione degli errori contiene una politica di nuovi tentativi completa, con backoff e jitter.
Errori comuni
- **
site_urlsbagliato.** Invia la pagina che mostra il widget, non la homepage. - Token scaduto. Un token usato dopo circa due minuti viene rifiutato. Risolvi subito prima di inviare.
- Sessione mancante. Un POST senza i cookie della pagina può fallire anche con un token valido.
- **Alcuni siti richiedono
rqdata.** Se la pagina fornisce un valorerqdataper il widget, passalo nella richiesta come campo opzionalerqdata. - Widget invisibile. Se non c'è una casella di spunta e il sito avvia il widget dal proprio codice, aggiungi
"is_invisible": truealla richiesta. La guida ai captcha invisibili mostra come restituire il token.
Prova gratuita
Crea un account e inizia con il credito di prova gratuito, senza carta. Esegui l'esempio qui sopra su un modulo di tua proprietà prima di inserirlo in un lavoro più grande. Per il costo delle risoluzioni a volume, consulta le tariffe attuali.
Registrare ogni risoluzione
Registra una riga per ogni risoluzione: la sitekey, l'host della pagina, l'errorId, l'errorCode in caso di errore e la durata della chiamata. Escludi la chiave API e qualsiasi password del proxy. Queste righe ti dicono se un'esecuzione lenta è lenta a causa della pagina, del proxy o del solver. Sono anche la prima cosa che ti servirà se apri una richiesta di supporto.
Risolvere in un ciclo
Se il tuo script risolve molti captcha uno dopo l'altro, mantieni il ciclo semplice. Risolvi, invia, controlla il risultato, e solo allora passa al successivo. Non risolvere in anticipo e accodare i token, perché ognuno scade entro circa due minuti. Una breve pausa tra una risoluzione e l'altra sullo stesso sito mantiene la tua frequenza di richieste vicina a quella che produrrebbe una persona.