C#'ta Selenium ile CAPTCHA API'sini kullanın
solvethree'yi HttpClient ile çağırın, görevin hazır olmasını bekleyin, ardından solution.token değerini uygulamanızın CAPTCHA alanına yerleştirin. Chrome, hedef sayfayı açmadan önce aynı proxy'yi ve döndürülen tarayıcı kimliğini kullanmalıdır.
Aşağıdaki örnek, size ait bir formu göndermek için .NET 8 ve Selenium Chrome kullanır. Bu, doğrudan bir REST entegrasyonudur; resmi bir C# SDK'sı veya Selenium eklentisi değildir.
Bu sayfada
Projeyi ve hedefi hazırlayın
- Varsayılan örtük using yönergeleri etkin olan bir .NET 8 konsol projesi kullanın.
Selenium.WebDriverveSelenium.SupportNuGet paketlerini, her ikisi de4.52.0sürümünde olacak şekilde ekleyin. - Chrome'u yerel olarak yükleyin. Selenium Manager uyumlu bir Chrome sürücüsü sağlar.
- Hedef ana makine adı için çalışma alanınızın erişebildiği etkin bir site profili olduğundan emin olun. Ana makine adı ve eylem göndermek profil oluşturmaz; önce site profili kurulum talimatlarını uygulayın.
- URL'sinde kimlik bilgileri bulunmayan, IP izin listesindeki bir proxy kullanın. Örnek, aynı proxy'yi solvethree'ye ve Chrome'a iletir.
| Değişken | Sağlanacak değer |
|---|---|
SOLVETHREE_API_KEY | Çalışma alanınızın API anahtarı. Anahtarı sayfada değil, otomasyonu çalıştıran güvenilir makinede tutun. |
SOLVETHREE_PROXY | Hem çözüm hem de tarayıcıdan gönderim için kullanılan, IP izin listesindeki proxy URL'si. |
TARGET_URL | Uygulamanızın form sayfasının tam URL'si. Örnek, görevin site alanı için bu URL'nin ana makine adını çıkarır. |
Entegrasyonunuz başka bir eylem kullanıyorsa örnekteki action değerini login yerine o eylemle değiştirin. Örnek, varsayılan recaptchaType değeri olan enterprise-v3 değerini kullanır; görev isteğinde type veya url alanı gerekmez.
Görevi oluşturun ve formu gönderin
API yardımcı kodu, çalışma alanı anahtarınızla kimlik doğrular ve başarılı yanıt gövdesini ayrıştırmadan önce başarısız HTTP yanıtlarını reddeder. Program tek bir görev oluşturur, durum pending veya solving olduğu sürece kimliğiyle sorgular ve Chrome'u yalnızca görev ready olduğunda başlatır.
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.30 saniyelik HTTP zaman aşımı, 180 saniyelik API süre sınırı ve 20 saniyelik Selenium beklemesi bu örneğin ayarlarıdır; hizmetin süre garantileri değildir. Bunları uygulamanızın zaman aşımı politikasına göre ayarlayın.
Token aktarımını uygulamanıza uyarlayın
- 1.
Proxy ile döndürülen kimliği birlikte kullanın
ChromeOptions, özgün proxy'yi ve
solution.userAgentdeğerini uygular. CDP komutları, sayfaya gitmeden önce ağ işlevlerini etkinleştirir vesec-ch-uabaşlığınısolution.secChUadeğerinden ayarlar. Bu sırayı koruyun; önce sayfayı açıp ardından kimliği değiştirmeyin. - 2.
Token'ı uygulamanın okuduğu yere yazın
Örnek,
g-recaptcha-responseadlı alanı bulur,solution.tokendeğerini atar ve bir input olayı tetikler. Uygulamanız token'ı başka bir yerden okuyorsa bu aktarımı değiştirin. Bir alanı doldurmak, yalnızca giden uygulama isteği gerçekten bu alanın değerini içeriyorsa işe yarar. - 3.
Gönderim ve başarı seçicilerini değiştirin
Örnek,
button[type=submit]öğesine tıklar ve kimliğisuccessolan bir öğeyi bekler. Gerçek uygulamanızın seçicilerini kullanın ve yalnızca düğmeye tıklandığını değil, gönderilen işlemin başarılı olduğunu doğrulayan bir başarı göstergesi seçin.
Hazır bir görev, çözümün kullanılabilir olduğu anlamına gelir. Gönderim sonrası kontrol ayrıdır: uygulama isteğini kabul edip etmeyeceğine yine hedef karar verir.
Gereksiz görevler oluşturmadan hataları ele alın
- API yardımcı kodu, bir HTTP yanıtı üzerine istisna fırlatır.
HTTP durumunu ve hata yanıtını inceleyin. Bu, bir görevin
faileddurumuna geçmesinden farklıdır.Şunu deneyin: Yeniden denemeden önce bildirilen istek veya kimlik doğrulama sorununu düzeltin. Değiştirilmemiş geçersiz girdileri tekrar tekrar göndermeyin.
- Görev
faileddurumuna geçer. errorCodeveerroralanlarını okuyun;site-unreachable, olası görev hatalarından biridir.Şunu deneyin: Bu görevin durumunu sorgulamayı bırakın ve bildirilen nedeni giderin. Başarısız çözümlerin ücretleri iade edilir.
- Görev hazırdır ancak hedef gönderimi reddeder.
Önce giden uygulama isteğini inceleyin: görev kimliği veya eski bir token yerine
solution.tokendeğerini içeriyor mu? Ardından proxy'yi, kullanıcı aracısını, istemci ipuçlarını ve hedef URL'yi kontrol edin.Şunu deneyin: Başka bir çözüm için ödeme yapmadan önce token aktarımını veya kimlik uyuşmazlığını düzeltin.
- Selenium, gönder düğmesine tıkladıktan sonra zaman aşımına uğrar.
Sayfayı ve uygulama yanıtını inceleyin.
successseçicisi örneğe özgüdür; evrensel bir kabul göstergesi değildir.Şunu deneyin: Bunu uygulamanızın gerçek başarı koşuluyla değiştirin veya uygulamanın döndürdüğü ret yanıtını ele alın.
Örnek bir requestId üretir ancak bunu sizin için kalıcı olarak saklamaz. Zaman aşımından kurtarma gerekiyorsa oluşturmadan önce bu değeri görev girdilerinin birebir aynısıyla birlikte kaydedin. Oluşturma zaman aşımına uğrarsa mevcut görevi kurtarmak için aynı girdileri aynı kimlikle yeniden gönderin; yalnızca yanıt kayboldu diye yeni bir kimlik üretmeyin. Bir kimliği farklı girdilerle yeniden kullanmak çakışmaya yol açar. Görev kimliği zaten elinizdeyse bunun yerine o görevi alın.
Kaynaklar ve API referansı
İlk görevinizi çalıştırın.
$5 çalışma alanı kredisiyle başlayın.