Scarnox · Blog

Captcha solver C# ile: HttpClient kullanan .NET örneği (2026)

C#'ta captcha solver, HttpClient etrafında yazılmış küçük bir sınıftır. Scarnox API'sine sitekey'i ve sayfa URL'sini gönderir, token'ı JSON yanıtından okur ve bunu sitenin formuna gönderirsiniz. Bu rehber .NET 8 için bu sınıfı yazar. Kapsam, Scarnox'un bugün proxysiz olarak çözdüğü PopularCaptcha'dır.

Ücretsiz deneme kredisiyle, kredi kartı gerekmeden başlayın ve kodu başka bir yerde çalıştırmadan önce sahibi olduğunuz bir sayfada deneyin.

Gereksinimler

Projeyi oluşturun

dotnet new console -n CaptchaDemo
cd CaptchaDemo

Ek paket gerekmez. System.Net.Http ve System.Text.Json çatının parçasıdır.

Solver sınıfı

Aşağıdaki sınıf, Bearer başlığı ve 185 saniyelik zaman aşımı olan tek bir HttpClient sahiplenir. Token'ı döndürür ya da API'nin hata metniyle birlikte bir istisna fırlatır:

// 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;
        }

        // Çağrı token hazır olduğunda döner. Polling yoktur.
        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; }
}

errorId kontrolü en önemli satırdır. API başarıda 0 döndürür. Başka her değer errorCode ve errorDescription ile gelir ve sınıf ikisini de dışarı taşır.

Token'ı gönderin

Token, sitenin formuna gider. Formu yükleyen oturumun GET ile POST arasında yeniden kullanılması için çerez konteyneri olan ikinci bir HttpClient kullanın:

// 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 = "";

// Geçici hataları yeniden dene. Başarısız çözümler ücretlendirilmez.
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) };

// Önce GET yap, böylece site oturum çerezini ayarlar.
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}");

Çalıştırın:

set SCARNOX_API_KEY=scarnox_YOURAPIKEY
dotnet run

PowerShell'de bunun yerine $env:SCARNOX_API_KEY = "scarnox_YOURAPIKEY" kullanın.

Neden bu yapıda

**Solver başına bir HttpClient.** HttpClient her çağrıda yeniden oluşturulmak yerine yeniden kullanılmak için tasarlanmıştır. Solver bir tane sahiplenir ve işi bitince onu serbest bırakır.

185 saniyelik zaman aşımı. API token hazır olana kadar bloke olur. Daha kısa bir zaman aşımı, bitmek üzere olan çözümleri iptal eder.

Tipli deserialization. ReadFromJsonAsync JSON'u CreateTaskResponse üzerine eşler; böylece hata ve token kontrolleri normal C# gibi okunur.

Form gönderimi. Site hem h-captcha-response hem g-recaptcha-response alır; çünkü siteler birini ya da diğerini okur. Çerez konteyneri GET ile POST arasında oturumu korur.

Zamanlama

Token yaklaşık iki dakikada süresi dolar. Çözümü göndermeden hemen önce yapın. Bir toplu işte erken çözüp çok sonra gönderirseniz token bayatlar. Captcha token süresi ayrıntıları anlatır.

Görünmez widget'lar

Widget görünmezse SolveAsync metoduna invisible: true geçin. İstek o zaman is_invisible: true içerir. Bazı sayfalar, sunucu tarafındaki bir istemcinin tetikleyemediği bir JavaScript callback'i gerektirir. Bu durumda bir tarayıcı otomasyon aracı daha iyi bir seçimdir. Kalıpları görünmez captcha rehberi kapsar.

Sorumlu scraping

Program herkese açık sayfaları scrape ediyorsa önce robots.txt dosyasını ve sitenin koşullarını kontrol edin. İstekler arasında bir gecikme koyun ve ihtiyacınız olan kişisel veriyi tutun. Yasal arka plan için web scraping yasal mı bölümüne bakın.

Fiyatlandırma

Scarnox başarılı her çözüm için ücretlendirir; başarısız çözümler ücretlendirilmez. Oranlar için fiyatlandırma sayfasına bakın. Ücretsiz deneme kredisiyle, kredi kartı gerekmeden başlayın.

Sonraki adımlar