Captcha-Solver in C# mit HttpClient: ein .NET-Beispiel (2026)
In C# ist ein Captcha-Solver eine kleine Klasse um HttpClient. Sie senden den Sitekey und die Seiten-URL an die Scarnox-API, lesen das Token aus der JSON-Antwort und reichen es an das Formular der Website weiter. Dieser Leitfaden baut diese Klasse für .NET 8, für PopularCaptcha, das Scarnox heute proxyless löst.
Starten Sie mit einer kostenlosen Testphase, ganz ohne Karte und probieren Sie den Code an einer Seite aus, die Ihnen gehört, bevor Sie ihn an anderer Stelle einsetzen.
Voraussetzungen
- .NET 8 SDK (
dotnet --version). - Ein Scarnox-API-Schlüssel, gelesen aus einer Umgebungsvariable.
- Der Sitekey des PopularCaptcha-Widgets der Seite. Hilfe beim Finden gibt wie Sie einen Captcha-Sitekey finden.
Das Projekt anlegen
dotnet new console -n CaptchaDemo
cd CaptchaDemo
Zusätzliche Pakete sind nicht nötig. System.Net.Http und System.Text.Json gehören zum Framework.
Die Solver-Klasse
Die folgende Klasse besitzt einen HttpClient mit dem Bearer-Header und einem Timeout von 185 Sekunden. Sie gibt das Token zurück oder wirft eine Ausnahme mit dem Fehlertext der API:
// ScarnoxSolver.cs
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
public sealed class ScarnoxSolver : IDisposable
{
private const string ApiUrl = "https://api.scarnox.com/api/tasks/create";
private readonly HttpClient _http;
public ScarnoxSolver(string apiKey)
{
_http = new HttpClient { Timeout = TimeSpan.FromSeconds(185) };
_http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
}
public async Task<string> SolveAsync(
string sitekey,
string pageUrl,
bool invisible = false,
CancellationToken ct = default)
{
var body = new Dictionary<string, object>
{
["captcha_type"] = "PopularCaptchaTaskProxyless",
["site_key"] = sitekey,
["site_url"] = pageUrl,
};
if (invisible)
{
body["is_invisible"] = true;
}
// Der Aufruf kehrt zurück, sobald das Token bereit ist. Es gibt kein Polling.
using var resp = await _http.PostAsJsonAsync(ApiUrl, body, ct);
var data = await resp.Content.ReadFromJsonAsync<CreateTaskResponse>(cancellationToken: ct)
?? throw new InvalidOperationException(
$"HTTP {(int)resp.StatusCode}: empty response");
if (data.ErrorId != 0)
{
throw new InvalidOperationException($"{data.ErrorCode}: {data.ErrorDescription}");
}
return data.Solution?.Token
?? throw new InvalidOperationException("Response had no token");
}
public void Dispose() => _http.Dispose();
}
public sealed class CreateTaskResponse
{
[JsonPropertyName("errorId")]
public int ErrorId { get; set; }
[JsonPropertyName("errorCode")]
public string? ErrorCode { get; set; }
[JsonPropertyName("errorDescription")]
public string? ErrorDescription { get; set; }
[JsonPropertyName("solution")]
public Solution? Solution { get; set; }
}
public sealed class Solution
{
[JsonPropertyName("token")]
public string? Token { get; set; }
}
Die errorId-Prüfung ist die wichtigste Zeile. Die API liefert 0 bei Erfolg. Jeder andere Wert kommt mit errorCode und errorDescription, und die Klasse gibt beides aus.
Das Token absenden
Das Token geht an das Formular der Website. Verwenden Sie einen zweiten HttpClient mit einem Cookie-Container, damit die Sitzung, die das Formular geladen hat, beim POST wiederverwendet wird:
// Program.cs
using System.Net;
var apiKey = Environment.GetEnvironmentVariable("SCARNOX_API_KEY")
?? throw new InvalidOperationException("Set SCARNOX_API_KEY");
const string pageUrl = "https://example.com/signup";
const string sitekey = "YOUR-SITEKEY-UUID";
using var solver = new ScarnoxSolver(apiKey);
string token = "";
// Vorübergehende Fehler wiederholen. Fehlgeschlagene Lösungen werden nicht berechnet.
for (int attempt = 1; attempt <= 3; attempt++)
{
try
{
token = await solver.SolveAsync(sitekey, pageUrl);
break;
}
catch (InvalidOperationException ex) when (attempt < 3)
{
Console.Error.WriteLine($"Attempt {attempt} failed: {ex.Message}");
await Task.Delay(TimeSpan.FromSeconds(attempt));
}
}
var cookies = new CookieContainer();
var handler = new HttpClientHandler { CookieContainer = cookies, UseCookies = true };
using var site = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(60) };
// Zuerst GET, damit die Website ihr Sitzungs-Cookie setzt.
await site.GetAsync(pageUrl);
using var form = new FormUrlEncodedContent(new Dictionary<string, string>
{
["email"] = "you@example.com",
["h-captcha-response"] = token,
["g-recaptcha-response"] = token,
});
using var response = await site.PostAsync(pageUrl, form);
Console.WriteLine($"Status: {(int)response.StatusCode}");
Ausführen:
set SCARNOX_API_KEY=scarnox_YOURAPIKEY
dotnet run
In PowerShell verwenden Sie stattdessen $env:SCARNOX_API_KEY = "scarnox_YOURAPIKEY".
Warum es so aufgebaut ist
**Ein HttpClient pro Solver.** HttpClient ist dafür gedacht, wiederverwendet zu werden, nicht für jeden Aufruf neu erstellt. Der Solver besitzt einen und gibt ihn am Ende frei.
Ein Timeout von 185 Sekunden. Die API blockiert, bis das Token bereit ist. Ein kürzeres Timeout bricht Lösungen ab, die kurz vor dem Abschluss standen.
Typisierte Deserialisierung. ReadFromJsonAsync bildet das JSON auf CreateTaskResponse ab, sodass die Fehler- und Token-Prüfungen wie normaler C#-Code aussehen.
Das Formularabsenden. Die Website erhält sowohl h-captcha-response als auch g-recaptcha-response, da Websites das eine oder das andere lesen. Der Cookie-Container hält die Sitzung zwischen GET und POST aufrecht.
Timing
Das Token läuft nach etwa zwei Minuten ab. Lösen Sie direkt vor dem Absenden. Wenn Sie in einem Batch früh lösen und viel später absenden, ist das Token veraltet. Ablauf von Captcha-Tokens erklärt die Details.
Unsichtbare Widgets
Übergeben Sie invisible: true an SolveAsync, wenn das Widget unsichtbar ist. Die Anfrage enthält dann is_invisible: true. Manche Seiten brauchen einen JavaScript-Callback, den ein serverseitiger Client nicht auslösen kann. In diesem Fall ist ein Browser-Automatisierungswerkzeug die bessere Wahl. Der Leitfaden unsichtbares Captcha behandelt die Muster.
Verantwortungsvoll scrapen
Wenn das Programm öffentliche Seiten scrapt, prüfen Sie zuerst die robots.txt und die Nutzungsbedingungen der Website. Verwenden Sie eine Verzögerung zwischen den Anfragen und behalten Sie nur die personenbezogenen Daten, die Sie brauchen. Den rechtlichen Hintergrund finden Sie unter ist Web Scraping legal.
Preise
Scarnox rechnet pro erfolgreicher Lösung ab, fehlgeschlagene Lösungen sind kostenlos. Die Tarife finden Sie auf der Preisseite. Starten Sie mit einer kostenlosen Testphase, ganz ohne Karte.