Scarnox · Blog

Risolutore captcha con Selenium in Python: esempio funzionante (2026)

Selenium pilota un vero browser, quindi la pagina viene renderizzata e i suoi script vengono eseguiti come farebbero per una persona. L'unico passaggio che non può fare è risolvere il widget PopularCaptcha. Questa guida aggiunge quel passaggio: leggere la sitekey dalla pagina renderizzata, ottenere un token con una chiamata API, scriverlo nel modulo e inviare.

Riguarda il widget PopularCaptcha, che Scarnox risolve oggi in modalità proxyless. Inizia con il credito di prova gratuito, senza carta e prova lo script su un modulo di test prima.

Cosa deve fare Selenium

Il flusso ha quattro parti:

  1. Carica la pagina e attendi che il widget venga renderizzato.
  2. Leggi l'attributo data-sitekey dal widget.
  3. Ottieni un token dall'API e inseriscilo nel modulo.
  4. Invia il modulo prima che il token scada.

La terza parte è l'unica che tocca il captcha. Tutto il resto è normale lavoro con Selenium.

Installa i pacchetti

pip install selenium requests

Selenium 4.6 e versioni successive trovano da sole un ChromeDriver compatibile, quindi non serve scaricare il driver a mano.

Lo script completo

import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

API_KEY = "scarnox_YOURAPIKEY"
API_URL = "https://api.scarnox.com/api/tasks/create"
PAGE_URL = "https://example.com/signup"


def solve(sitekey: str, page_url: str, invisible: bool = False) -> str:
    body = {
        "captcha_type": "PopularCaptchaTaskProxyless",
        "site_key": sitekey,
        "site_url": page_url,
    }
    if invisible:
        body["is_invisible"] = True

    r = requests.post(
        API_URL,
        headers={"Authorization": f"Bearer {API_KEY}"},
        json=body,
        timeout=185,  # attende 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"]


INJECT_TOKEN_JS = """
const token = arguments[0];
let field = document.querySelector('[name="h-captcha-response"]');
if (!field) {
    field = document.createElement("textarea");
    field.name = "h-captcha-response";
    field.style.display = "none";
    document.querySelector("form").appendChild(field);
}
field.value = token;
let extra = document.querySelector('[name="g-recaptcha-response"]');
if (!extra) {
    extra = document.createElement("textarea");
    extra.name = "g-recaptcha-response";
    extra.style.display = "none";
    document.querySelector("form").appendChild(extra);
}
extra.value = token;
"""


def main() -> None:
    driver = webdriver.Chrome()
    try:
        driver.get(PAGE_URL)

        widget = WebDriverWait(driver, 15).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "[data-sitekey]"))
        )
        sitekey = widget.get_attribute("data-sitekey")
        invisible = widget.get_attribute("data-size") == "invisible"

        token = solve(sitekey, driver.current_url, invisible=invisible)

        # Compila prima gli altri campi, poi inserisci il token subito prima dell'invio,
        # perché il token scade in circa due minuti.
        driver.find_element(By.NAME, "email").send_keys("you@example.com")
        driver.execute_script(INJECT_TOKEN_JS, token)

        driver.find_element(By.CSS_SELECTOR, "form button[type=submit]").click()
        WebDriverWait(driver, 15).until(EC.url_changes(PAGE_URL))
        print("Submitted. Now at:", driver.current_url)
    finally:
        driver.quit()


if __name__ == "__main__":
    main()

Lo script non ha bisogno di un proxy per una risoluzione PopularCaptcha proxyless. Ometti il campo proxy e lascia che il sito veda la tua connessione normale.

L'ordine delle operazioni è la parte che più spesso va storta. Compila prima il resto del modulo, poi risolvi, poi inserisci, poi clicca. Se risolvi prima di digitare negli altri campi, una pagina lenta o un modulo lento possono far superare al token la sua durata di vita. Mantieni il più breve possibile il distacco tra la risoluzione e il clic, e controlla la pagina dei risultati per un errore prima di presumere che il captcha sia stato superato.

Perché il token viene inserito con JavaScript

La maggior parte dei widget PopularCaptcha scrive il token in un'area di testo nascosta chiamata h-captcha-response quando una persona lo risolve. Poiché Selenium non vede una persona, lo script scrive lo stesso campo da solo. Lo snippet INJECT_TOKEN_JS fa due cose:

Compila anche g-recaptcha-response, perché molti siti leggono quel nome per compatibilità.

Widget invisibili

Un widget invisibile non ha una casella di spunta. Gira in background e di solito si avvia all'invio del modulo. Lo script controlla data-size="invisible" e invia is_invisible: true quando lo trova. Alcuni siti collegano anche una callback JavaScript al widget. Se il modulo resta fermo dopo aver inserito il token, cerca un attributo data-callback e chiama quella funzione con il token. La nostra guida ai captcha invisibili copre questo caso.

Uso nei test

Selenium è anche lo strumento abituale per i test end-to-end. Se il tuo sito di staging mostra un captcha, lo stesso codice permette a un test di superarlo. Tieni l'ambiente di test separato dalla produzione, e non eseguirlo su siti che non possiedi. L'impostazione delle suite di test è descritta in captcha nei test automatizzati.

Problemi comuni

Tariffe

Paghi per ogni risoluzione riuscita. Le risoluzioni fallite non vengono addebitate. Consulta le tariffe attuali e inizia con il credito di prova gratuito, senza carta.

Passi successivi