Scarnox · Blog

Token captcha scaduto: cause e come risolvere

Un token captcha è una prova di breve durata che una sfida è stata superata. I token PopularCaptcha di Scarnox scadono circa due minuti dopo l'emissione. Se invii un token dopo quella finestra, il sito rifiuta il form, spesso con un messaggio che dice che il captcha è scaduto o non valido. La soluzione riguarda quasi sempre il timing: risolvi il captcha il più vicino possibile all'invio, usa ogni token una sola volta e riprova solo quando sai che il primo tentativo non è stato accettato.

Perché i token scadono

Un token non è una credenziale permanente. Il sito vuole sapere che una persona (o un solver che agisce per conto di una persona) ha completato la sfida di recente, quindi gli dà una vita breve. Il conteggio inizia quando il token viene emesso, non quando chiami per la prima volta l'API. Tutto ciò che succede tra la risoluzione e l'invio consuma i due minuti.

Cause comuni

La soluzione: risolvi subito prima di inviare

Il pattern più semplice e affidabile è rendere la risoluzione e l'invio un unico passaggio. Richiedi un token, mettilo nel form, invia il form e non fare nulla di lento nel mezzo:

import requests

API_KEY = "scarnox_YOURAPIKEY"
CREATE_URL = "https://api.scarnox.com/api/tasks/create"

def fresh_token(sitekey: str, page_url: str) -> str:
    r = requests.post(
        CREATE_URL,
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={
            "captcha_type": "PopularCaptchaTaskProxyless",
            "site_key": sitekey,
            "site_url": page_url,
        },
        timeout=185,  # la chiamata blocca finché il token non è pronto
    )
    data = r.json()
    if data.get("errorId") != 0:
        raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
    return data["solution"]["token"]

def submit_form(page_url: str, sitekey: str, form: dict) -> requests.Response:
    token = fresh_token(sitekey, page_url)  # risolvi subito prima dell'invio
    return requests.post(
        page_url,
        data={**form, "h-captcha-response": token, "g-recaptcha-response": token},
        timeout=30,
    )

Nota che submit_form non tiene un token in una cache o in una coda. Ne chiede uno, lo invia e va avanti. Le risoluzioni fallite non vengono addebitate, quindi una richiesta fallita non ti costa nulla lato risoluzione.

Riprova in sicurezza

Alcuni siti rifiutano un token scaduto con una risposta chiara. Altri restituiscono una pagina normale con un messaggio di errore al suo interno, quindi il solo codice di stato non basta. Guarda la risposta che il sito restituisce davvero per un token scaduto, e costruisci il controllo su quella. Un ciclo di retry potrebbe essere così:

def submit_with_retry(page_url: str, sitekey: str, form: dict, attempts: int = 2):
    for _ in range(attempts):
        resp = submit_form(page_url, sitekey, form)
        if resp.status_code < 400 and "captcha" not in resp.text.lower():
            return resp  # accettato, per quanto mostra la risposta di questo sito
    raise RuntimeError("captcha token rejected after retries")

Fai attenzione ai retry sui form che creano qualcosa. Se il primo tentativo è stato davvero accettato ma il tuo codice ha interpretato male la risposta, un retry può creare un account, un ordine o un messaggio duplicato. Riprova solo quando sei sicuro che il primo invio non sia stato accettato, e rendi il controllo specifico per il sito con cui lavori.

Mantieni onesta la tempistica

Errori comuni

Registra abbastanza per diagnosticarlo

Quando un invio fallisce, registra l'ora in cui il token è stato emesso, l'ora in cui il form è stato inviato, lo stato HTTP e i primi qualche centinaio di caratteri della risposta. Con questi quattro valori puoi capire a colpo d'occhio se il token è scaduto o se il sito l'ha rifiutato per un altro motivo. Non registrare il token completo nei log condivisi, perché un token valido è una credenziale per quella singola sfida.

Cosa controllare se continua a fallire

  1. Stampa il tempo tra la restituzione del token e l'invio del form.
  2. Verifica che site_url corrisponda alla pagina che mostra il captcha.
  3. Verifica che la sitekey sia stata letta dalla pagina attuale, non da una copia vecchia.
  4. Verifica i nomi dei campi del form. I token PopularCaptcha vanno in h-captcha-response, e spesso anche in g-recaptcha-response.

Per l'elenco completo delle risposte di errore e come gestire ciascuna, vedi gestione degli errori del solver captcha.

Prossimi passi