Scarnox · Blog

Jak rozwiązać PopularCaptcha w Pythonie (działający przykład, 2026)

Jeśli twój skrypt w Pythonie trafił na PopularCaptcha, nie potrzebujesz farmy przeglądarek ani własnego modelu. Potrzebujesz sitekey strony, jednego żądania POST i tokena, który wróci.

Ten przewodnik prowadzi od zera do działającego tokena w około pięć minut: uzyskaj klucz API, znajdź sitekey, poproś o token, wyślij go do formularza i obsłuż przypadki błędów, które pojawiają się, gdy skrypt działa bez nadzoru. Nieudane rozwiązania są bezpłatne, więc ponowienie kosztuje tylko czas.

Scarnox rozwiązuje PopularCaptcha dziś, proxyless albo z własnym proxy. Inne typy captcha, takie jak reCAPTCHA, Cloudflare Turnstile i AWS WAF, są wkrótce, dlatego każdy przykład tutaj używa PopularCaptcha. Przegląd typów captcha wyjaśnia, czym różnią się pozostałe.

1. Uzyskaj klucz API

Załóż konto i zacznij z darmowym kredytem próbnym, bez karty. Twój klucz API znajduje się w panelu. Trzymaj go poza kodem źródłowym i odczytuj ze zmiennej środowiskowej:

export SCARNOX_KEY="scarnox_YOURAPIKEY"

2. Znajdź sitekey

Otwórz stronę z captcha, otwórz DevTools i wyszukaj data-sitekey w panelu Elements. Sitekey PopularCaptcha to UUID:

<div class="h-captcha" data-sitekey="10000000-ffff-ffff-ffff-000000000001"></div>

Brak data-sitekey w HTML? Widget prawdopodobnie renderuje JavaScript. Sprawdź w zakładce Network żądanie konfiguracji widgetu; jego parametr zapytania sitekey to ten, którego potrzebujesz. Inne sposoby znalezienia obejmują adres iframe i niewidoczne widgety.

Jako site_url wyślij adres strony, która pokazuje widget. Najważniejszy jest host, ale pełny adres strony to bezpieczny wybór.

3. Poproś o 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,  # wywołanie blokuje się, aż token będzie gotowy
    )
    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], "...")

To cała integracja. Nie ma pętli odpytywania ani drugiego wywołania „pobierz wynik”. Żądanie wraca, gdy token jest gotowy, więc jedynym ważnym ustawieniem jest limit czasu wystarczająco długi, by pokryć wolne rozwiązanie. Użyj około 185 sekund.

Udana odpowiedź ma errorId równe 0, a token znajduje się pod solution.token. Każdy inny errorId oznacza, że rozwiązanie się nie udało, a odpowiedź zawiera errorCode i errorDescription wyjaśniające dlaczego.

4. Wyślij token

Token trafia tam, gdzie strona oczekuje odpowiedzi captcha. Dla PopularCaptcha jest to niemal zawsze pole formularza o nazwie h-captcha-response. Wiele stron akceptuje też g-recaptcha-response, więc wyślij oba:

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)

Dwa szczegóły mają znaczenie. Prawdziwe strony zwykle sprawdzają też ciasteczka sesji z załadowania strony, więc załaduj formularz tym samym requests.Session przed wysłaniem. I wysyłaj na adres action formularza, który nie zawsze jest adresem strony.

Rozwiązuj tuż przed wysłaniem. Token wygasa w ciągu około dwóch minut, więc nie pobieraj go na początku długiego zadania i nie trzymaj go w zapasie. Jeśli strona odrzuca token, otwórz formularz w DevTools i potwierdź nazwy ukrytych pól.

5. Obsłuż błędy

Nieudane rozwiązania są bezpłatne, więc ponowienie kosztuje tylko czas. Niektóre błędy nigdy nie zakończą się sukcesem przy ponowieniu, więc nie zapętlaj na ślepo. Sprawdzaj errorId za każdym razem, zapisuj errorCode i errorDescription i ponawiaj tylko przejściowe błędy.

Błędy sieciowe wymagają osobnej obsługi, bo requests zgłasza wyjątek, zanim w ogóle powstanie odpowiedź:

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)

Przewodnik o obsłudze błędów zawiera kompletną politykę ponowień z backoffem i jitterem.

Typowe błędy

Wypróbuj za darmo

Załóż konto i zacznij z darmowym kredytem próbnym, bez karty. Uruchom powyższy przykład na formularzu, który posiadasz, zanim podłączysz go do większego zadania. Koszty przy dużym wolumenie znajdziesz w aktualnym cenniku.

Logowanie każdego rozwiązania

Zapisuj jedną linię na rozwiązanie: sitekey, host strony, errorId, errorCode przy błędzie i czas trwania wywołania. Nie zapisuj klucza API ani hasła proxy. Te linie pokazują, czy wolny przebieg jest wolny z powodu strony, proxy czy solvera. Są też pierwszą rzeczą, której będziesz potrzebować, gdy otworzysz zgłoszenie do pomocy technicznej.

Rozwiązywanie w pętli

Jeśli skrypt rozwiązuje wiele captcha pod rząd, utrzymuj pętlę prostą. Rozwiąż, wyślij, sprawdź wynik i dopiero potem przejdź dalej. Nie rozwiązuj z wyprzedzeniem i nie kolejkuj tokenów, bo każdy wygasa w ciągu około dwóch minut. Krótka pauza między rozwiązaniami na tej samej stronie utrzymuje tempo zapytań zbliżone do tego, co wygenerowałby człowiek.

Dalsze kroki