C# में HCaptchaAsync से hCaptcha कैसे हल करें (.NET 8+)

C# में hCaptcha हल करने के लिए CapSkip NuGet पैकेज से HCaptchaAsync को widget के sitekey और पेज के पते के साथ call करें। लौटने वाले SolveResult में token, respKey और वह User-Agent होता है जिसके साथ token मिला, और आप token को उसी User-Agent के साथ अपना फ़ॉर्म post करते हैं। वही method checkbox, invisible और Enterprise widgets को संभालता है। यह call CapSkip hCaptcha सॉल्वर को जाती है, जो आपके अपने Windows PC पर चलता है, और फिक्स्ड कीमत वाला लाइसेंस होने से दूसरी कोशिश पर कुछ खर्च नहीं होता।
आपको क्या चाहिए
- CapSkip 4.0.0 या बाद का, जो किसी Windows PC पर चल रहा हो, यानी वह रिलीज़ जिसने hCaptcha जोड़ा। इंस्टॉल करने के चरण यहाँ दिए हैं: सेटअप गाइड.
- कम से कम .NET 8 SDK, और CapSkip NuGet पैकेज 1.6.0 या बाद का, जिसमें पहली बार HCaptchaAsync आया। पैकेज netstandard2.0 को target करता है और System.Text.Json 8.0.5 पर निर्भर है। मेरे पास एक SDK इंस्टॉल है, 10.0.100, और मैंने सब कुछ CapSkip 1.6.0 के साथ सिर्फ़ net10.0 और net8.0 पर चलाया।
- एक PowerShell prompt, और ऐसा पेज जिसे ऑटोमेट करने की आपको अनुमति हो और जिस पर hCaptcha widget दिखे, उसके sitekey के साथ।
- CapSkip के लिए एक पता। Local mode सिर्फ़ 127.0.0.1 पर जवाब देता है, उसी PC के programs के लिए। Server mode आपके नेटवर्क या पब्लिक IP पर भी सुनता है, इसलिए दूसरी मशीन का program वही API call कर सकता है। यह चुनाव कनेक्शन सेटिंग्स में तय होता है।
टेस्ट सेटअप: NuGet से असली CapSkip 1.6.0 पैकेज और मेरे अपने दो mock सर्वर, कोई असली hCaptcha साइट नहीं। एक mock CapSkip app की जगह खड़ा है और API दस्तावेज़ के hCaptcha सेक्शन का पालन करता है। दूसरा sign-up पेज की भूमिका निभाता है और proxy की तरह भी काम कर सकता है। उसके नियम (session cookie, एक Referer या Origin, और वह User-Agent जिसके साथ token आया) मेरे अपने चुनाव हैं, hCaptcha के नहीं, जिसके डेवलपर दस्तावेज़ बताते हैं कि असली साइट token की जाँच कैसे करती है। मैंने पैकेज का source उसके v1.6.0 tag पर पढ़ा और असली CapSkip app को कुछ नहीं भेजा, इसलिए मेरे पास असली हल का कोई समय नहीं है।
चरण 1: project बनाएँ और CapSkip इंस्टॉल करें
एक console project बनाएँ और पैकेज इंस्टॉल करें। नया project implicit usings और nullable reference types चालू करता है, और इस कोड को दोनों चाहिए। वर्ज़न बताए बिना dotnet add package सबसे नया रिलीज़ लेता है, जो मेरे चलाने पर 1.6.0 था।
dotnet new console -o hcaptcha-demo cd hcaptcha-demo dotnet add package CapSkip
Program.cs में सब कुछ मिटा दें, template की Console.WriteLine पंक्ति समेत, फिर नीचे के तीन C# ब्लॉक क्रम से चिपकाएँ, चरण 2 से शुरू करके। सिर्फ़ पहले ब्लॉक में using पंक्तियाँ हैं, और आख़िरी ब्लॉक के आने से पहले कुछ नहीं चलता।
चरण 2: HCaptchaAsync को call करें
sitekey पेज पर होता है। ज़्यादातर पेज उसे widget container पर data-sitekey के रूप में छापते हैं, और script से बना widget उसे hcaptcha.render() के sitekey option के रूप में देता है। HCaptchaAsync sitekey, पेज का पता, एक options dictionary और एक CancellationToken लेता है। उसका typed overload options से पहले invisible नाम का एक bool लेता है: true invisible=1 भेजता है और false कुछ नहीं भेजता। जो Enterprise साइट rqdata सेट करती है, उसका मान data key के तहत जाता है, हर टास्क के लिए नया। proxy एक Proxy object है जिसमें type (HTTP, HTTPS, SOCKS5 या SOCKS5H) और login:password@host:port string होती है। port को पूरा लिखें, क्योंकि Uri.Authority डिफ़ॉल्ट port को छोड़ देता है। mock रन में invisible, data और proxy in.php तक पहुँचे।
using System.Net;
using System.Text.RegularExpressions;
using CapSkip;
using SolverTimeout = CapSkip.TimeoutException; // System.TimeoutException is in scope too (CS0104)
static class Solve
{
// Local mode. In Server mode, use your server's address instead. If API Key
// Validation is on in CapSkip, also pass apiKey: "YOUR_KEY" here.
static readonly CapSkipClient Client = new(host: "127.0.0.1", port: 8080);
public static Task<SolveResult> Run(string siteKey, string pageUrl, bool invisible,
string? rqData, Uri? proxy, CancellationToken ct)
{
var options = new Dictionary<string, object?>();
if (rqData is not null) options["data"] = rqData; // Enterprise rqdata, fresh per task
if (proxy is not null)
{
// Uri.Authority drops a default port such as 80, so build host:port by hand.
var login = proxy.UserInfo.Length > 0 ? Uri.UnescapeDataString(proxy.UserInfo) + "@" : "";
options["proxy"] = new Proxy(proxy.Scheme.ToUpperInvariant(), $"{login}{proxy.Host}:{proxy.Port}");
}
// invisible: false sends nothing, true sends invisible=1.
return Client.HCaptchaAsync(siteKey, pageUrl, invisible, options, ct);
}
}नतीजे में जानने लायक चार properties हैं। Token और Code में एक ही string होती है। RespKey वह दूसरा मान है जो hCaptcha widget को देता है, वही जो ब्राउज़र में hcaptcha.getRespKey() लौटाता है। ज़्यादातर साइटें उसे कभी नहीं पढ़तीं, और जब कुछ न हो तो वह null नहीं, खाली string होता है। UserAgent उस ब्राउज़र की User-Agent string है जिसके साथ token मिला। जवाब में कोई User-Agent न हो तो वह null रहता है, और तब चरण 3 कोई User-Agent नहीं भेजता और मेरी mock साइट ने post ठुकरा दिया।
SDK किसी भी रिक्वेस्ट से पहले आपके arguments जाँचता है। खाली sitekey, ऐसा पेज पता जो absolute http या https नहीं है, 0, 1, true या false के अलावा कोई invisible मान, और ऐसा कोई भी parameter जो CapSkip का hCaptcha API नहीं लेता, जिनमें 2Captcha का domain भी है, ये ValidationException उठाते हैं, और mock को इनमें से किसी के लिए कोई टास्क नहीं मिला। इसके अलावा SDK टास्क सबमिट करता है और तुरंत poll करता है, फिर 0.25 सेकंड बाद, और उसके बाद अंतराल दोगुना होता हुआ 5 सेकंड तक। mock के सामने polls submit के बाद 0, 0.25, 0.75, 1.75, 3.75, 7.75 और 12.75 सेकंड के 0.15 सेकंड के भीतर आए।
इंतज़ार RecaptchaTimeout के बाद TimeoutException के साथ खत्म होता है, जो 300 सेकंड है, जब तक आप constructor को recaptchaTimeout या किसी एक call को timeout option न दें। hCaptcha को वह लंबा timeout इसलिए मिलता है कि widget असली ब्राउज़र में पास किया जाता है, और दस्तावेज़ कहते हैं कि एक हल में आम तौर पर 10 से 30 सेकंड लगते हैं। deadline polls के बीच जाँची जाती है: 22 सेकंड के timeout और कभी जवाब न देने वाले mock के साथ exception call के 22.9 सेकंड बाद आया।
SDK जो भी exception फेंकता है वह CapSkipError को extend करता है। ValidationException एक स्थानीय इनकार है। NetworkException का मतलब है कि रिक्वेस्ट नाकाम हुई या CapSkip ने HTTP 200 के साथ जवाब नहीं दिया। ApiException का मतलब है कि CapSkip ने error के साथ जवाब दिया, और उसका संदेश पूरी reply body है (mock के सामने, poll के बाद JSON और submit के बाद सादा text), इसलिए code उसके अंदर बैठा होता है। दो जाल हैं। TimeoutException System में भी मौजूद है, और implicit usings System को import करती हैं, इसलिए using CapSkip के बगल में सादा TimeoutException CS0104 के साथ फेल होता है, यानी ambiguous reference। पहला ब्लॉक SDK की class को SolverTimeout के नाम से alias करता है। और submit के दौरान चलने वाला CancellationToken cancellation को लपेटे हुए NetworkException बनकर निकलता है, जबकि polling के दौरान चलने वाला TaskCanceledException बनकर निकलता है।
चरण 3: फ़ॉर्म को अपने ही handler से post करें
पैकेज CapSkip के लिए अपना HttpClient रखता है, इसलिए नीचे कुछ भी उसे साझा नहीं करता। form post अलग है, क्योंकि cookie jar handler का होता है और दो sign-up को cookies साझा नहीं करनी चाहिए। Site.SignUp अपने ही CookieContainer वाला handler बनाता है, उसके चारों ओर एक client लपेटता है और आख़िर में दोनों को dispose करता है। Microsoft के HttpClient दिशानिर्देश एक से ज़्यादा instance रखने की एक वजह के रूप में अलग-अलग cookie containers को गिनाते हैं।
पेज लोड पहले आता है, ताकि पेज की cookies post के साथ वापस जाएँ। दोनों रिक्वेस्ट में नतीजे वाला User-Agent होता है। HttpClient जब तक आप न दें कोई नहीं भेजता: उस पंक्ति को हटाने पर mock साइट ने, जो उसे token से मिलाकर जाँचती है, खाली User-Agent देखा और हर post ठुकरा दिया। post में Referer और Origin भी होते हैं, क्योंकि HttpClient कोई नहीं भेजता। मेरी mock साइट को इनमें से एक चाहिए, जो मेरा चुना हुआ नियम है, और मैंने नहीं नापा कि कितनी असली साइटें ऐसा करती हैं। token h-captcha-response और g-recaptcha-response में जाता है। वह एक बार काम करता है और दस्तावेज़ों के अनुसार करीब दो मिनट चलता है, इसलिए उसे तुरंत post करें।
proxy वैकल्पिक है, हालाँकि दस्तावेज़ चेताते हैं कि एक ही IP से हलों की लगातार धारा वही है जिसे hCaptcha की rate limits पकड़ती हैं। आप जो Uri देते हैं वह Solve.Run के ज़रिए CapSkip को और इस handler को जाता है, क्योंकि दस्तावेज़ सख़्त साइटों के लिए चाहते हैं कि फ़ॉर्म उसी पते से आए जिससे हल हुआ। WebProxy पते में दिए login को अनदेखा करता है, इसलिए handler उसे एक NetworkCredential में उठा लेता है। Basic credentials माँगने वाले एक mock proxy ने उसे स्वीकार किया, password में प्रतिशत चिह्न होने पर भी। मैंने साइट वाला हिस्सा SOCKS के ज़रिए नहीं चलाया।
static class Site
{
// One HttpClient per sign-up, because the cookie jar belongs to the handler and two
// sign-ups must not share cookies. Dispose it when the sign-up is over.
public static async Task<(HttpStatusCode Status, string Body)> SignUp(
string pageUrl, SolveResult solved, string email, Uri? proxy, CancellationToken ct)
{
var handler = new HttpClientHandler { CookieContainer = new CookieContainer() };
if (proxy is not null)
{
var address = new UriBuilder(proxy.Scheme, proxy.Host, proxy.Port).Uri;
var login = proxy.UserInfo.Split(':', 2).Select(Uri.UnescapeDataString).ToArray();
handler.Proxy = new WebProxy(address)
{
Credentials = login.Length == 2 ? new NetworkCredential(login[0], login[1]) : null,
};
}
using var http = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(30) };
// The User-Agent the token was earned with, on the page load and on the post.
if (solved.UserAgent is not null)
http.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", solved.UserAgent);
using (await http.GetAsync(pageUrl, ct)) { } // the page's own cookies land in the jar
var origin = new Uri(pageUrl).GetLeftPart(UriPartial.Authority);
using var post = new HttpRequestMessage(HttpMethod.Post, pageUrl)
{
Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
["email"] = email, // your form's own fields go here
["h-captcha-response"] = solved.Token!, // always set on an hCaptcha result
["g-recaptcha-response"] = solved.Token!, // the widget fills both
}),
};
post.Headers.TryAddWithoutValidation("Referer", pageUrl); // HttpClient sends none
post.Headers.TryAddWithoutValidation("Origin", origin);
using var response = await http.SendAsync(post, ct);
return (response.StatusCode, await response.Content.ReadAsStringAsync(ct));
}
}चरण 4: पूरा C# में hCaptcha loop चलाएँ
आख़िरी ब्लॉक Main method है। PageUrl और SiteKey constants बदलें (जैसा चिपकाया गया है वह example.com को रिक्वेस्ट करता है, जिसमें कोई widget नहीं है), फिर project folder में dotnet run चलाएँ। वह एक CancellationTokenSource के तहत ज़्यादा से ज़्यादा तीन कोशिशें करता है, और हर कोशिश के अंदर SDK का अपना 300 सेकंड का इंतज़ार है। CapSkip 4.1.0 के source को मेरे पढ़ने के अनुसार, एक टास्क CapSkip के उसे unsolvable कहने से पहले 300 सेकंड तक चल सकता है, Max. Threads slot के लिए 250 सेकंड तक इंतज़ार करने के बाद, इसलिए load में recaptchaTimeout बढ़ाएँ।
दस्तावेज़ों के अनुसार ERROR_CAPTCHA_UNSOLVABLE वह अकेला code है जहाँ तुरंत नया टास्क मदद कर सकता है। ERROR_NO_SLOT_AVAILABLE, जो rate limit पार करने वाली key को मिलता है, 5 सेकंड रुककर दोबारा आज़माया जाता है। बाकी हर code रन खत्म कर देता है, और ValidationException भी, क्योंकि वही arguments फिर ठुकराए जाएँगे। जो साइट 400 या उससे ऊपर का जवाब दे, उसे नया टास्क और नया token मिलता है। 200 हमेशा सफलता नहीं होता, क्योंकि कई साइटें error को पेज के अंदर रखती हैं, इसलिए status जाँच को ऐसी चीज़ से बदलें जो सिर्फ़ सफलता में दिखे। जब form post का 30 सेकंड का HttpClient.Timeout खत्म होता है, तो आख़िरी catch उसे रिपोर्ट करता है।
static class Program
{
const string PageUrl = "https://example.com/signup"; // the page that shows the widget
const string SiteKey = "YOUR_SITEKEY"; // the data-sitekey of its h-captcha div
static readonly Uri? ProxyUri = null; // for example new Uri("http://user:[email protected]:8080")
// The reply body is the exception message, JSON on a poll and bare text on a submit.
static string ErrorCode(ApiException ex)
{
var found = Regex.Match(ex.Message, "ERROR_[A-Z_]+");
return found.Success ? found.Value : ex.Message;
}
static async Task<int> Main()
{
// One budget for every attempt. Cancelling it stops a wait or a request at once.
using var budget = new CancellationTokenSource(TimeSpan.FromMinutes(6));
try
{
for (var attempt = 1; attempt <= 3; attempt++)
{
SolveResult solved;
try
{
solved = await Solve.Run(SiteKey, PageUrl, invisible: false, rqData: null, ProxyUri, budget.Token);
}
catch (ApiException ex) when (ErrorCode(ex) is "ERROR_CAPTCHA_UNSOLVABLE" or "ERROR_NO_SLOT_AVAILABLE")
{
Console.WriteLine($"attempt {attempt}: {ErrorCode(ex)}, new task");
// The second code means the key is over its rate limit, so pause first.
if (ErrorCode(ex) == "ERROR_NO_SLOT_AVAILABLE") await Task.Delay(TimeSpan.FromSeconds(5), budget.Token);
continue;
}
var (status, body) = await Site.SignUp(PageUrl, solved, "[email protected]", ProxyUri, budget.Token);
if ((int)status < 400)
{
Console.WriteLine($"{(int)status} {body[..Math.Min(40, body.Length)]}");
return 0;
}
Console.WriteLine($"attempt {attempt}: the site answered {(int)status}, new token");
}
Console.WriteLine("no accepted form after 3 attempts");
}
// A cancelled submit surfaces as a NetworkException, a cancelled poll as a
// TaskCanceledException, so test the budget itself.
catch (Exception) when (budget.IsCancellationRequested) { Console.WriteLine("the 6 minute budget ran out"); }
catch (ApiException ex) { Console.WriteLine($"CapSkip answered {ErrorCode(ex)}"); }
catch (SolverTimeout ex) { Console.WriteLine($"no token in time: {ex.Message}"); }
catch (CapSkipError ex) { Console.WriteLine($"{ex.GetType().Name}: {ex.Message}"); }
catch (HttpRequestException ex) { Console.WriteLine($"request failed: {ex.Message}"); }
catch (TaskCanceledException) { Console.WriteLine("the site did not answer in 30 seconds"); } // HttpClient.Timeout
return 1;
}
}mock के सामने, जो किसी असली साइट के बारे में कुछ साबित नहीं करते, हर पंक्ति net10.0 और net8.0 पर एक जैसी आई।
| mock सेटिंग | प्रोग्राम ने क्या किया |
|---|---|
| token SDK के डिफ़ॉल्ट के साथ 7वें poll पर तैयार | एक टास्क, polls submit के बाद 0, 0.25, 0.75, 1.75, 3.75, 7.75 और 12.75 सेकंड के 0.15 सेकंड के भीतर, फिर 200 |
| दो इनकार (ERROR_CAPTCHA_UNSOLVABLE, या रुकने के साथ ERROR_NO_SLOT_AVAILABLE), फिर सफलता; या हर बार इनकार | तीसरे टास्क पर 200; या तीन कोशिश की पंक्तियाँ, exit code 1 और साइट को कोई रिक्वेस्ट नहीं |
| साइट पहला form post 403 के साथ ठुकराती है | नया टास्क और token, फिर 200 |
| खाली sitekey | एक ValidationException पंक्ति और exit code 1, mock को कोई टास्क नहीं |
| ERROR_ZERO_BALANCE, ERROR_PROXY_CONNECT_REFUSED या ERROR_RECAPTCHA_INVALID_SITEKEY | हर एक ने रन को एक टास्क के बाद रोक दिया |
| Invisible call, Enterprise call, login के साथ या बिना proxy | in.php ने invisible=1, data का मान, या proxytype HTTP और पता देखा, और साइट की रिक्वेस्ट proxy mock से होकर आईं |
| constructor में apiKey, key validation चालू | key submit और हर poll तक पहुँची। डिफ़ॉल्ट key को ERROR_KEY_DOES_NOT_EXIST मिला |
| recaptchaTimeout 22 और कभी जवाब न देने वाला mock | TimeoutException, call के 22.9 सेकंड बाद |
| 2 सेकंड का budget, poll के इंतज़ार या अटके in.php के दौरान | दोनों बार 2.0 सेकंड बाद budget का संदेश |
| CapSkip पर या साइट पर कुछ नहीं सुन रहा; साइट का ऐसा पेज जो कभी जवाब नहीं देता | NetworkException; रिक्वेस्ट नाकाम; 30 सेकंड बाद 30 सेकंड वाला संदेश |
| एक साथ तीन sign-up | तीन टास्क, तीन sessions, posts पर तीन User-Agent, तीन 200 जवाब |
दो snippets बाकी सब कुछ संभालते हैं। पहला call को invisible या Enterprise widget के लिए बदलता है। दूसरा एक साथ कई accounts साइन अप करता है: Main में बाहरी try के braces के बीच की पंक्तियों की जगह इसे रखें, और catch पंक्तियाँ रहने दें। हर sign-up अपना handler बनाता है, और mock हर टास्क को अपना User-Agent देता है, इसलिए गड़बड़ी होती तो posts फेल हो जाते। snippet कोई rqData नहीं देता, इसलिए Enterprise साइट के लिए lambda के अंदर नया मान पढ़ें।
// Snippet, not part of Program.cs. In Main, replace the Solve.Run line with one of these. // An invisible widget (data-size="invisible"): solved = await Solve.Run(SiteKey, PageUrl, invisible: true, rqData: null, ProxyUri, budget.Token); // An Enterprise widget. Read a fresh rqdata value from the page before every attempt, // because it is single use. The literal below stands in for that code. solved = await Solve.Run(SiteKey, PageUrl, invisible: false, rqData: "RQDATA_FROM_THE_PAGE", ProxyUri, budget.Token);
// Snippet, not part of Program.cs. In Main, replace the lines between the braces of the outer try
// with these, and keep the catch lines. Three accounts sign up at once on one SDK client.
var emails = new[] { "[email protected]", "[email protected]", "[email protected]" };
var codes = await Task.WhenAll(emails.Select(async email =>
{
var solved = await Solve.Run(SiteKey, PageUrl, false, null, ProxyUri, budget.Token);
var (status, _) = await Site.SignUp(PageUrl, solved, email, ProxyUri, budget.Token);
return (int)status;
}));
Console.WriteLine(string.Join(" ", codes));
return codes.All(c => c < 400) ? 0 : 1;आम errors
| आप जो देखते हैं | कारण | फिक्स |
|---|---|---|
| ValidationException | भेजने से पहले ठुकराया गया: खाली sitekey, ऐसा पेज पता जो absolute http या https नहीं है, गलत invisible मान, या domain जैसा parameter जो hCaptcha API नहीं लेता | argument ठीक करें। retry से मदद नहीं मिल सकती |
| ERROR_RECAPTCHA_INVALID_SITEKEY | sitekey को उस पेज के लिए ठुकराया गया | data-sitekey फिर से कॉपी करें और पेज का पता जाँचें |
| ERROR_CAPTCHA_UNSOLVABLE | CapSkip widget को पास नहीं कर पाया | loop नया टास्क सबमिट करता है, तीन बार तक |
| ERROR_PROXY_FORMAT या ERROR_PROXY_CONNECT_REFUSED | CapSkip proxy मान को पढ़ नहीं पाया, या उसके ज़रिए target तक पहुँच नहीं पाया (दूसरा मामला मैंने सिर्फ़ simulate किया) | scheme, host और port वाला Uri दें, और proxy को अलग से टेस्ट करें |
| ERROR_WRONG_METHOD | 4.0.0 से पुराना CapSkip hCaptcha method को शायद न जानता हो (टेस्ट नहीं किया) | CapSkip को 4.0.0 या बाद के वर्ज़न पर अपडेट करें |
| ERROR_NO_SLOT_AVAILABLE, ERROR_ZERO_BALANCE या ERROR_IP_NOT_ALLOWED | सिर्फ़ API Key Validation चालू होने पर। 4.1.0 के source को मेरे पढ़ने के अनुसार: key अपनी rate limit से ऊपर है, उसके credits खत्म हैं, या एक-डिवाइस वाली key कहीं और इस्तेमाल हो रही है | loop पहले पर रुककर दोबारा आज़माता है। बाकी के लिए CapSkip में key की सेटिंग्स बदलें |
| ERROR_WRONG_USER_KEY या ERROR_KEY_DOES_NOT_EXIST | API Key Validation चालू है, और आपके constructor call में apiKey गायब या गलत है | CapSkipClient पंक्ति में सही apiKey दें |
| TimeoutException | recaptchaTimeout के भीतर कोई token नहीं आया। खाली जवाब को तैयार नहीं गिना जाता, इसलिए SDK poll करता रहता है | CapSkip Monitor में टास्क देखें, फिर recaptchaTimeout बढ़ाएँ |
| call शुरू होते ही NetworkException | उस host और port पर कोई program जवाब नहीं देता। inner exception एक HttpRequestException है | CapSkip चलाएँ, फिर कनेक्शन सेटिंग्स से उसका host और port अपने constructor call में कॉपी करें |
| Error CS0104: ambiguous reference | TimeoutException System में भी है और CapSkip में भी। System.ComponentModel.DataAnnotations को import करते ही ValidationException भी इसी तरह टकराता है | SDK की class को alias करें, जैसा पहला ब्लॉक करता है, या उसका पूरा नाम लिखें |
| सही दिखने वाला token ठुकरा दिया जाता है | दस्तावेज़ ये कारण बताते हैं: दोबारा इस्तेमाल हुआ token, करीब दो मिनट से पुराना token, और नतीजे वाले से अलग User-Agent। मेरी mock ने गायब User-Agent, Referer, Origin या session cookie को भी ठुकराया। 407 का मतलब है कि proxy को login चाहिए | हर token को Site.SignUp से एक बार, तुरंत post करें |
सर्वर पर CapSkip का इस्तेमाल
Server mode में CapSkip आपके नेटवर्क पते या पब्लिक IP पर सुनता है, इसलिए C# में वही hCaptcha कोड दूसरे PC, Windows VPS या hosted platform से भी चलता है। Server mode के लिए CapSkip का administrator के रूप में चलना ज़रूरी है, और सेटअप गाइड स्थिर पब्लिक IP की सलाह देता है। CapSkipClient पंक्ति में host को सर्वर के पते से बदलें और बाकी कुछ नहीं बदलता।
Server mode शुरू होने पर CapSkip अपना port हर पते के लिए खोल देता है, इसलिए उसे अपनी अपेक्षित मशीनों तक सीमित रखने के लिए बाकी के लिए Windows Firewall block rule जोड़ें, और CapSkipClient पंक्ति में apiKey के साथ API Key Validation चालू करें। हल अब सर्वर पर चलता है, इसलिए hCaptcha उसी मशीन का नेटवर्क देखता है।
FAQ
C# में invisible या Enterprise hCaptcha कैसे हल करूँ?
उसी HCaptchaAsync call से। जिस widget का data-size invisible है, उसके लिए invisible bool में true दें। जो Enterprise साइट rqdata सेट करती है, उसके लिए मान को data key के तहत दें और हर टास्क के लिए नया पढ़ें, क्योंकि दस्तावेज़ कहते हैं कि साइट उसे एक चैलेंज के लिए जारी करती है। चरण 4 का पहला snippet दोनों दिखाता है।
क्या मैं SDK को IHttpClientFactory के साथ register कर सकता हूँ?
register करने को कुछ नहीं है। पैकेज CapSkip को अपनी calls एक अपने static HttpClient से करता है। Site.SignUp को भी factory से बाहर रखें: Microsoft के दिशानिर्देश चेताते हैं कि pooled handlers अपना CookieContainer साझा करते हैं।
साइट वह token क्यों ठुकराती है जो CapSkip ने मुझे दिया?
सख़्त साइट वह token ठुकरा सकती है जिसे hCaptcha ने जोखिम भरा स्कोर किया, भले ही widget पास हुआ हो, और Enterprise साइटें आम मामला हैं। दस्तावेज़ hCaptcha सेटिंग्स में High score mode की सलाह देते हैं। उसके लिए CapSkip PC पर Google Chrome चाहिए, और 4.1.0 के source को मेरे पढ़ने के अनुसार वह डिफ़ॉल्ट रूप से चालू है। मेरे पास इसे आज़माने को कोई सख़्त साइट नहीं थी।
C# में hCaptcha हल करना तीन चीज़ों पर आकर टिकता है: एक HCaptchaAsync call, एक ऐसा loop जो सिर्फ़ उन codes पर दोबारा कोशिश करे जिनके लिए यह सार्थक है, और सही cookies व User-Agent वाले handler से एक form post। CapSkip एक लोकल कैप्चा बायपास है, जो फिक्स्ड कीमत वाले लाइसेंस पर चलता है, इसलिए एक और कोशिश में बस उतना ही समय लगता है जितना वह लेती है। .NET में बाकी CAPTCHA प्रकारों के लिए C# कैप्चा सॉल्वर पेज देखें। widget कैसे पास होता है, यह hCaptcha डेमो में दिखाया गया है।
