HttpClient के साथ C# में captcha solver: .NET उदाहरण (2026)
C# में captcha solver HttpClient के आसपास एक छोटी class है। आप Scarnox API को sitekey और page URL भेजते हैं, JSON response से token पढ़ते हैं, और उसे site के form में submit करते हैं। यह guide .NET 8 के लिए वह class बनाती है, PopularCaptcha के लिए, जिसे Scarnox आज proxyless आधार पर solve करता है।
मुफ़्त ट्रायल क्रेडिट से शुरू करें, कार्ड की ज़रूरत नहीं और किसी और चीज़ पर चलाने से पहले अपने किसी page पर code आज़माएँ।
ज़रूरतें
- .NET 8 SDK (
dotnet --version)। - Scarnox API key, जो environment variable से पढ़ी जाए।
- Page के PopularCaptcha widget की sitekey। उसे ढूँढने में मदद के लिए captcha sitekey कैसे खोजें देखें।
Project बनाएँ
dotnet new console -n CaptchaDemo
cd CaptchaDemo
अतिरिक्त packages की ज़रूरत नहीं है। System.Net.Http और System.Text.Json framework का हिस्सा हैं।
Solver class
नीचे की class एक HttpClient रखती है जिसमें Bearer header और 185 सेकंड का timeout है। वह token लौटाती है या API के error text के साथ throw करती है:
// 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;
}
// token तैयार होते ही call लौट आती है। यहाँ 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; }
}
errorId की जाँच सबसे अहम पंक्ति है। API सफलता पर 0 लौटाता है। कोई और मान errorCode और errorDescription के साथ आता है, और class दोनों को सामने लाती है।
Token submit करें
Token site के form पर जाता है। एक दूसरा HttpClient इस्तेमाल करें जिसमें cookie container हो, ताकि form लोड करने वाला session POST पर दोबारा इस्तेमाल हो:
// 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 = "";
// अस्थायी विफलताओं को retry करें। विफल solves का चार्ज नहीं लगता।
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) };
// पहले GET करें ताकि site session cookie सेट कर दे।
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}");
चलाएँ:
set SCARNOX_API_KEY=scarnox_YOURAPIKEY
dotnet run
PowerShell में इसके बजाय $env:SCARNOX_API_KEY = "scarnox_YOURAPIKEY" इस्तेमाल करें।
यह ढाँचा ऐसा क्यों है
**हर solver के लिए एक HttpClient।** HttpClient को दोबारा इस्तेमाल करने के लिए बनाया गया है, हर call के लिए नया बनाने के लिए नहीं। Solver एक रखता है और अंत में उसे dispose करता है।
185 सेकंड का timeout। API तब तक रुकती है जब तक token तैयार न हो। छोटा timeout उन solves को रद्द कर देगा जो लगभग पूरे होने वाले थे।
Typed deserialization। ReadFromJsonAsync, JSON को CreateTaskResponse पर मैप करता है, इसलिए error और token की जाँच सामान्य C# जैसी पढ़ी जाती है।
Form submit। Site को h-captcha-response और g-recaptcha-response दोनों मिलते हैं, क्योंकि sites इनमें से कोई एक पढ़ती हैं। Cookie container GET और POST के बीच session रखता है।
समय
Token लगभग दो मिनट में expire होता है। Solve ठीक submit के पहले करें। अगर आप batch में पहले solve करते हैं और बहुत बाद में submit करते हैं, तो token पुराना हो जाएगा। captcha token expiry विवरण बताती है।
Invisible widgets
जब widget invisible हो, तो SolveAsync को invisible: true पास करें। तब request में is_invisible: true जुड़ जाता है। कुछ pages को ऐसे JavaScript callback की ज़रूरत होती है जिसे server-side client ट्रिगर नहीं कर सकता। ऐसे में browser automation tool बेहतर विकल्प है। पैटर्न के लिए invisible captcha guide देखें।
ज़िम्मेदारी से scrape करें
अगर program सार्वजनिक pages scrape करता है, तो पहले robots.txt और site के terms जाँचें। Requests के बीच delay रखें, और केवल वही personal data रखें जिसकी ज़रूरत है। कानूनी पृष्ठभूमि के लिए क्या web scraping legal है देखें।
कीमत
Scarnox हर सफल solve पर बिल करता है, और विफल solves मुफ़्त हैं। दरों के लिए मौजूदा pricing देखें। मुफ़्त ट्रायल क्रेडिट से शुरू करें, कार्ड की ज़रूरत नहीं।