Die CAPTCHA-API mit Selenium in C# verwenden
Rufen Sie solvethree mit HttpClient auf, warten Sie, bis die Aufgabe fertig ist, und tragen Sie dann solution.token in das CAPTCHA-Feld Ihrer Anwendung ein. Chrome muss denselben Proxy und die zurückgegebene Browseridentität verwenden, bevor die Zielseite geöffnet wird.
Das folgende Beispiel verwendet .NET 8 und Selenium Chrome, um ein eigenes Formular abzusenden. Es handelt sich um eine direkte REST-Integration, nicht um ein offizielles C#-SDK oder Selenium-Plugin.
Auf dieser Seite
Projekt und Ziel vorbereiten
- Verwenden Sie ein .NET-8-Konsolenprojekt mit den standardmäßig aktivierten impliziten using-Direktiven. Fügen Sie die NuGet-Pakete
Selenium.WebDriverundSelenium.Supporthinzu, beide in Version4.52.0. - Installieren Sie Chrome lokal. Selenium Manager stellt einen kompatiblen Chrome-Treiber bereit.
- Stellen Sie sicher, dass für den Zielhostnamen ein aktives Websiteprofil in Ihrem Workspace verfügbar ist. Durch das Senden eines Hostnamens und einer Aktion wird keines erstellt; befolgen Sie zuerst die Anleitung zur Einrichtung eines Websiteprofils.
- Verwenden Sie einen per IP freigeschalteten Proxy ohne Zugangsdaten in der URL. Das Beispiel übergibt denselben Proxy an solvethree und Chrome.
| Variable | Anzugebender Wert |
|---|---|
SOLVETHREE_API_KEY | Ihr Workspace-API-Schlüssel. Bewahren Sie ihn auf dem vertrauenswürdigen Rechner auf, auf dem die Automatisierung läuft, nicht in der Seite. |
SOLVETHREE_PROXY | Die URL des per IP freigeschalteten Proxys, der sowohl zum Lösen als auch zum Übermitteln im Browser verwendet wird. |
TARGET_URL | Die vollständige URL der Formularseite Ihrer Anwendung. Das Beispiel extrahiert daraus den Hostnamen für site der Aufgabe. |
Ändern Sie action im Beispiel von login, falls Ihre Integration eine andere Aktion verwendet. Das Beispiel verwendet den Standardwert für recaptchaType, enterprise-v3; die Aufgabenanfrage benötigt kein Feld type oder url.
Aufgabe erstellen und Formular absenden
Die API-Hilfsfunktion authentifiziert sich mit Ihrem Workspace-Schlüssel und weist HTTP-Antworten ohne Erfolgsstatus zurück, bevor sie Erfolgsdaten parst. Das Programm erstellt eine Aufgabe, fragt ihre ID per Polling ab, solange der Status pending oder solving ist, und startet Chrome erst, wenn die Aufgabe ready ist.
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json.Nodes;
var key = Environment.GetEnvironmentVariable("SOLVETHREE_API_KEY")
?? throw new Exception("Set SOLVETHREE_API_KEY");
var proxy = Environment.GetEnvironmentVariable("SOLVETHREE_PROXY")
?? throw new Exception("Set SOLVETHREE_PROXY");
using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", key);
using var deadline = new CancellationTokenSource(TimeSpan.FromSeconds(180));
async Task<JsonObject> Api(HttpMethod method, string path, JsonObject? body = null)
{
using var request = new HttpRequestMessage(method, "https://api.solvethree.com/v1" + path);
if (body is not null)
request.Content = new StringContent(body.ToJsonString(), Encoding.UTF8, "application/json");
using var response = await http.SendAsync(request, deadline.Token);
response.EnsureSuccessStatusCode();
return JsonNode.Parse(await response.Content.ReadAsStringAsync(deadline.Token))!.AsObject();
}
var requestId = Guid.NewGuid().ToString(); // Save with these inputs for recovery.
var input = new JsonObject {
["site"] = new Uri(Environment.GetEnvironmentVariable("TARGET_URL") ?? throw new Exception("Set TARGET_URL")).Host, ["action"] = "login",
["proxy"] = proxy, ["requestId"] = requestId
};
var task = await Api(HttpMethod.Post, "/tasks?waitMs=0", input);
while (task["status"]!.GetValue<string>() is "pending" or "solving")
{
var id = Uri.EscapeDataString(task["id"]!.GetValue<string>());
task = await Api(HttpMethod.Get, "/tasks/" + id + "?waitMs=15000");
if (task["status"]!.GetValue<string>() is "pending" or "solving")
await Task.Delay(1000, deadline.Token);
}
if (task["status"]!.GetValue<string>() != "ready")
throw new Exception("Task failed: " + task["errorCode"]?.GetValue<string>()
+ ": " + task["error"]?.GetValue<string>());
var solution = task["solution"]!.AsObject();
// Use solution["token"], ["userAgent"] and ["secChUa"] with the original proxy.
Console.WriteLine("Ready task: " + task["id"]!.GetValue<string>());
var target = Environment.GetEnvironmentVariable("TARGET_URL") ?? throw new Exception("Set TARGET_URL");
if (!string.IsNullOrEmpty(new Uri(proxy).UserInfo)) throw new Exception("Use an IP-allowlisted proxy");
var options = new ChromeOptions();
options.AddArgument("--proxy-server=" + proxy);
options.AddArgument("--user-agent=" + solution["userAgent"]!.GetValue<string>());
using var browser = new ChromeDriver(options);
browser.ExecuteCdpCommand("Network.enable", new Dictionary<string, object>());
browser.ExecuteCdpCommand("Network.setExtraHTTPHeaders", new Dictionary<string, object> {
["headers"] = new Dictionary<string, object> { ["sec-ch-ua"] = solution["secChUa"]!.GetValue<string>() }
});
browser.Navigate().GoToUrl(target);
var wait = new WebDriverWait(browser, TimeSpan.FromSeconds(20));
var field = wait.Until(driver => driver.FindElement(By.Name("g-recaptcha-response")));
browser.ExecuteScript("arguments[0].value=arguments[1]; arguments[0].dispatchEvent(new Event('input',{bubbles:true}));",
field, solution["token"]!.GetValue<string>());
browser.FindElement(By.CssSelector("button[type=submit]")).Click();
wait.Until(driver => driver.FindElement(By.Id("success"))); // Your application's success marker.Das HTTP-Timeout von 30 Sekunden, das API-Zeitlimit von 180 Sekunden und die Selenium-Wartezeit von 20 Sekunden sind Einstellungen dieses Beispiels, keine Zeitgarantien des Dienstes. Passen Sie diese an die Timeout-Richtlinie Ihrer Anwendung an.
Übergabe an Ihre Anwendung anpassen
- 1.
Proxy und zurückgegebene Identität zusammen verwenden
ChromeOptions wendet den ursprünglichen Proxy und
solution.userAgentan. Die CDP-Befehle aktivieren die Netzwerkfunktionen und setzensec-ch-uaaussolution.secChUavor der Navigation. Halten Sie diese Reihenfolge ein; öffnen Sie nicht zuerst die Seite, um die Identität anschließend zu ändern. - 2.
Token dort eintragen, wo die Anwendung es liest
Das Beispiel sucht ein Feld namens
g-recaptcha-response, weist ihmsolution.tokenzu und löst ein input-Event aus. Ersetzen Sie diese Übergabe, falls Ihre Anwendung das Token an einer anderen Stelle liest. Das Ausfüllen eines Feldes hilft nur, wenn die ausgehende Anwendungsanfrage seinen Wert tatsächlich enthält. - 3.
Selektoren für Absenden und Erfolg ersetzen
Das Beispiel klickt auf
button[type=submit]und wartet auf ein Element mit der IDsuccess. Verwenden Sie Selektoren aus Ihrer tatsächlichen Anwendung und wählen Sie ein Erfolgsmerkmal, das den Erfolg des übermittelten Vorgangs bestätigt – nicht nur, dass die Schaltfläche angeklickt wurde.
Eine fertige Aufgabe bedeutet, dass eine Lösung verfügbar ist. Die Prüfung nach dem Absenden ist davon getrennt: Das Ziel entscheidet weiterhin, ob es die Anwendungsanfrage akzeptiert.
Fehler behandeln, ohne unnötige Aufgaben zu erstellen
- Die API-Hilfsfunktion löst bei einer HTTP-Antwort eine Ausnahme aus.
Prüfen Sie den HTTP-Status und die Fehlerantwort. Dies unterscheidet sich davon, dass eine Aufgabe den Status
failederreicht.Probiere Folgendes: Beheben Sie das gemeldete Anfrage- oder Authentifizierungsproblem vor einem erneuten Versuch. Senden Sie nicht fortlaufend unveränderte ungültige Eingaben.
- Die Aufgabe erreicht den Status
failed. Lesen Sie
errorCodeunderror;site-unreachableist ein möglicher Aufgabenfehler.Probiere Folgendes: Beenden Sie das Polling für diese Aufgabe und beheben Sie die gemeldete Ursache. Fehlgeschlagene Lösungsversuche werden erstattet.
- Die Aufgabe ist fertig, aber das Ziel lehnt die Übermittlung ab.
Prüfen Sie zuerst die ausgehende Anwendungsanfrage: Enthält sie
solution.tokenstatt der Aufgaben-ID oder eines alten Tokens? Prüfen Sie anschließend den Proxy, den User-Agent, die Client Hints und die Ziel-URL.Probiere Folgendes: Korrigieren Sie die Token-Übergabe oder die abweichende Identität, bevor Sie für einen weiteren Lösungsversuch bezahlen.
- Nach dem Klick auf Absenden tritt in Selenium ein Timeout auf.
Prüfen Sie die Seite und die Antwort der Anwendung. Der Selektor
successist ein Platzhalter im Beispiel, kein universelles Signal für eine Annahme.Probiere Folgendes: Ersetzen Sie ihn durch die tatsächliche Erfolgsbedingung Ihrer Anwendung oder behandeln Sie die von der Anwendung zurückgegebene Ablehnung.
Das Beispiel generiert eine requestId, speichert sie aber nicht dauerhaft für Sie. Speichern Sie sie vor dem Erstellen zusammen mit den exakten Aufgabeneingaben, wenn Sie eine Wiederherstellung nach einem Timeout benötigen. Tritt beim Erstellen ein Timeout auf, senden Sie dieselben Eingaben mit derselben ID erneut, um die vorhandene Aufgabe wiederherzustellen; generieren Sie nicht allein deshalb eine neue ID, weil die Antwort verloren gegangen ist. Die Wiederverwendung einer ID mit anderen Eingaben führt zu einem Konflikt. Wenn Sie die Aufgaben-ID bereits haben, rufen Sie stattdessen diese Aufgabe ab.
Quellen und API-Referenz
Führe deinen ersten Task aus.
Starte mit $5 Workspace-Guthaben.