Scarnox · Blog

Captcha-Solver in PHP mit cURL: ein funktionierendes Beispiel (2026)

PHP braucht nur die cURL-Erweiterung, die in den meisten Installationen enthalten ist, um ein Captcha zu lösen. Sie senden eine JSON-POST-Anfrage an die Scarnox-API, lesen solution.token aus der Antwort und reichen dieses Token an das Formular der Website weiter. Dieser Leitfaden führt durch den vollständigen PHP-Ablauf für PopularCaptcha, das Scarnox heute proxyless löst.

Starten Sie mit einer kostenlosen Testphase, ganz ohne Karte und probieren Sie das Skript an einer Seite aus, die Ihnen gehört, bevor Sie es anderswo einsetzen.

Voraussetzungen

Die Solver-Funktion

Diese Funktion sendet eine Anfrage an die API, prüft errorId und gibt das Token zurück. Bei jedem Fehler wirft sie eine Ausnahme, sodass der Aufrufer entscheiden kann, ob er wiederholt:

<?php
declare(strict_types=1);

const SCARNOX_API_KEY = 'scarnox_YOURAPIKEY';
const SCARNOX_API_URL = 'https://api.scarnox.com/api/tasks/create';

function solveCaptcha(string $sitekey, string $pageUrl, bool $invisible = false): string
{
    $body = [
        'captcha_type' => 'PopularCaptchaTaskProxyless',
        'site_key'     => $sitekey,
        'site_url'     => $pageUrl,
    ];
    if ($invisible) {
        $body['is_invisible'] = true;
    }

    $ch = curl_init(SCARNOX_API_URL);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode($body, JSON_THROW_ON_ERROR),
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . SCARNOX_API_KEY,
            'Content-Type: application/json',
        ],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 185, // der Aufruf kehrt zurück, sobald das Token bereit ist
    ]);

    $raw = curl_exec($ch);
    if ($raw === false) {
        $error = curl_error($ch);
        throw new RuntimeException('cURL error: ' . $error);
    }

    $data = json_decode((string) $raw, true);
    if (!is_array($data)) {
        throw new RuntimeException('Response was not JSON');
    }
    if (($data['errorId'] ?? 1) !== 0) {
        throw new RuntimeException(
            ($data['errorCode'] ?? 'ERROR') . ': ' . ($data['errorDescription'] ?? 'unknown')
        );
    }

    return (string) $data['solution']['token'];
}

Der Header Authorization verwendet das Präfix Bearer. Das Timeout beträgt 185 Sekunden, weil die API blockiert, bis das Token bereit ist, und es gibt keinen Polling-Schritt.

Vorübergehende Fehler wiederholen

Eine fehlgeschlagene Lösung wird nicht berechnet, ein paar Wiederholungen sind also günstig. Legen Sie die Schleife um den Aufruf und warten Sie nach jedem Fehler etwas länger:

function solveWithRetry(string $sitekey, string $pageUrl, int $attempts = 3): string
{
    $lastError = null;
    for ($i = 1; $i <= $attempts; $i++) {
        try {
            return solveCaptcha($sitekey, $pageUrl);
        } catch (RuntimeException $e) {
            $lastError = $e;
            fwrite(STDERR, "Attempt $i failed: " . $e->getMessage() . PHP_EOL);
            sleep($i);
        }
    }
    throw $lastError;
}

Eine vollständige Fehlerstrategie, einschließlich der Fehler, bei denen Sie aufhören sollten, finden Sie unter Fehlerbehandlung für Captcha-Solver.

Viele Websites binden das Captcha an die Sitzung, die das Formular geladen hat. Eine Cookie-Datei lässt cURL dieselben Cookies beim GET und beim POST senden. Die folgende Funktion sendet das Token an das Formular der Seite:

function submitToken(string $pageUrl, string $token): string
{
    $cookieFile = sys_get_temp_dir() . '/scarnox-cookies.txt';

    // Zuerst GET, damit die Website das Sitzungs-Cookie setzt.
    $ch = curl_init($pageUrl);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_COOKIEFILE     => $cookieFile,
        CURLOPT_COOKIEJAR      => $cookieFile,
        CURLOPT_TIMEOUT        => 60,
    ]);
    curl_exec($ch);

    // Dann das Formular mit dem Token in beiden Captcha-Feldern per POST senden.
    $fields = http_build_query([
        'email'                 => 'you@example.com',
        'h-captcha-response'    => $token,
        'g-recaptcha-response'  => $token,
    ]);

    curl_setopt_array($ch, [
        CURLOPT_POST       => true,
        CURLOPT_POSTFIELDS => $fields,
        CURLOPT_TIMEOUT    => 60,
    ]);
    $body = curl_exec($ch);
    if ($body === false) {
        throw new RuntimeException('Form submit failed: ' . curl_error($ch));
    }

    return (string) $body;
}

Zwei Dinge sind wichtig. Der GET läuft vor der Lösung, damit das Cookie gesetzt ist. Und das Token geht direkt nach der Lösung raus, weil es nach etwa zwei Minuten abläuft. Setzen Sie den Lösungsaufruf direkt vor diese Funktion, nicht zu Beginn eines langen Batches.

Die Cookie-Datei wird von jedem Aufruf im selben Prozess gemeinsam genutzt. Geben Sie daher jedem Konto oder jeder Sitzung eine eigene Datei, wenn Sie mehrere Registrierungen parallel laufen lassen. Andernfalls überschreibt eine Sitzung die Cookies einer anderen, und der zweite POST schlägt aus Gründen fehl, die wie ein Captcha-Problem aussehen, es aber nicht sind.

Alles zusammengesetzt

$pageUrl = 'https://example.com/signup';
$token   = solveWithRetry('YOUR-SITEKEY-UUID', $pageUrl);
$html    = submitToken($pageUrl, $token);

echo strlen($html) . " bytes returned\n";

Ausführen von der Kommandozeile:

php signup.php

Unsichtbare Widgets

Ist das Widget unsichtbar, rufen Sie solveCaptcha($sitekey, $pageUrl, true) auf. Das Feld is_invisible wird dann mit der Anfrage gesendet. Manche Seiten brauchen außerdem einen JavaScript-Callback mit dem Token, den ein serverseitiges Skript nicht auslösen kann. Verwenden Sie in diesem Fall ein Browser-Werkzeug. Der Leitfaden unsichtbares Captcha behandelt die Fälle.

Timing und Ablauf

Das Token ist etwa zwei Minuten gültig. Halten Sie Lösung und Absenden eng beieinander. Ablauf von Captcha-Tokens erklärt, wie Sie ein abgelaufenes von einem abgelehnten Token unterscheiden.

Verantwortungsvoll scrapen

Wenn Ihr PHP-Skript öffentliche Seiten scrapt, prüfen Sie vor dem Start die robots.txt und die Nutzungsbedingungen der Website. Fügen Sie eine Verzögerung zwischen den Anfragen hinzu und speichern Sie keine personenbezogenen Daten, die Sie nicht brauchen. Eine Captcha-Lösung ändert nichts daran, was Sie sammeln dürfen. Zur rechtlichen Seite siehe ist Web Scraping legal.

Preise

Sie zahlen pro erfolgreicher Lösung. Fehlgeschlagene Lösungen werden nicht berechnet. Die aktuellen Tarife finden Sie auf der Preisseite, und starten Sie mit einer kostenlosen Testphase, ganz ohne Karte.

Nächste Schritte