Last active
June 24, 2020 15:09
-
-
Save Panthere/606dbf5566c4224310f29633a7d59dcc to your computer and use it in GitHub Desktop.
2captcha C# Implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CaptchaResult | |
{ | |
#region Fields | |
/// <summary> | |
/// Captcha ID as provided by 2captcha | |
/// </summary> | |
public string ID; | |
/// <summary> | |
/// Token required to submit to the site | |
/// </summary> | |
public string Response; | |
/// <summary> | |
/// Is true if the captcha has been solved successfully. If false, Response is null | |
/// </summary> | |
public bool HasSolved; | |
private string _apiKey; | |
#endregion | |
#region Constructors | |
public CaptchaResult(string res, string id, string apiKey, bool hasSolved = false) | |
{ | |
Response = res; | |
ID = id; | |
HasSolved = hasSolved; | |
_apiKey = apiKey; | |
} | |
#endregion | |
#region Public Members | |
/// <summary> | |
/// Report the captcha as being invalid to 2captcha | |
/// </summary> | |
/// <returns>Captcha report submitted successfully</returns> | |
public bool ReportInvalid() | |
{ | |
try | |
{ | |
using (WebClient wc = new WebClient()) | |
{ | |
return wc.DownloadString(string.Format("{0}?key={1}&action=reportbad&id={2}", TwoCaptcha.RES_URL, _apiKey, ID)) == "OK_REPORT_RECORDED"; | |
} | |
} | |
catch (Exception ex) | |
{ | |
#if DEBUG | |
Debug.WriteLine("ReportInvalid: {0}", ex); | |
#endif | |
return false; | |
} | |
} | |
#endregion | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TwoCaptcha | |
{ | |
#region Consts | |
public const string IN_URL = "http://2captcha.com/in.php"; | |
public const string RES_URL = "http://2captcha.com/res.php"; | |
#endregion | |
#region Public Fields | |
/// <summary> | |
/// Site key from recaptcha for the site | |
/// </summary> | |
public string SiteKey; | |
/// <summary> | |
/// 2captcha API key | |
/// </summary> | |
public string APIKey; | |
/// <summary> | |
/// Site URL or domain to send to 2captcha | |
/// </summary> | |
public string SiteURL; | |
/// <summary> | |
/// Max amount of poll tries before it is marked as not solved | |
/// </summary> | |
public int MaxPollTries = 15; | |
/// <summary> | |
/// Max submit tries before it returns null | |
/// </summary> | |
public int MaxSubmitTries = 15; | |
#endregion | |
#region Properties | |
/// <summary> | |
/// The proxy sent to 2captcha when requesting a captcha to be solved | |
/// </summary> | |
public WebProxy AccessProxy | |
{ | |
get; | |
set; | |
} | |
#endregion | |
#region Constructors | |
/// <summary> | |
/// Creates a new instance of the 2captcha api without setting a proxy | |
/// </summary> | |
/// <param name="siteKey">ReCaptcha Site Key</param> | |
/// <param name="siteUrl">Url from the site for the site key</param> | |
public TwoCaptcha(string apiKey, string siteKey, string siteUrl) | |
: this(apiKey, siteKey, siteUrl, null) | |
{ | |
} | |
/// <summary> | |
/// Creates a new instance of the 2captcha api | |
/// </summary> | |
/// <param name="apiKey">2captcha API Key</param> | |
/// <param name="siteKey">ReCaptcha Site Key</param> | |
/// <param name="siteUrl">Url from the site for the site key</param> | |
/// <param name="accessProxy">Proxy to send to 2captcha for external use</param> | |
public TwoCaptcha(string apiKey, string siteKey, string siteUrl, WebProxy accessProxy) | |
{ | |
SiteKey = siteKey; | |
SiteURL = siteUrl; | |
APIKey = apiKey; | |
AccessProxy = accessProxy; | |
} | |
#endregion | |
#region Public Members | |
/// <summary> | |
/// Solve a new Google NoCaptcha for the provided site using the provided proxy. | |
/// </summary> | |
/// <returns>CaptchaResult containing the token required</returns> | |
public CaptchaResult SolveCaptcha() | |
{ | |
CaptchaResult captchaId = GetCaptchaID(); | |
if (captchaId == null) | |
return null; | |
// Kill me, yeah, I know, wow, thread.sleep in 2016 | |
Thread.Sleep(5000); | |
return PollCaptchaID(captchaId); | |
} | |
#endregion | |
#region Private Members | |
private CaptchaResult PollCaptchaID(CaptchaResult captchaId) | |
{ | |
int attemptsMax = MaxPollTries; | |
while ((attemptsMax--) > 0) | |
{ | |
try | |
{ | |
using (WebClient wc = new WebClient()) | |
{ | |
string resp = wc.DownloadString(string.Format("{0}?key={1}&action=get&id={2}", RES_URL, APIKey, captchaId.ID)); | |
if (resp.Contains("OK|")) | |
{ | |
captchaId.HasSolved = true; | |
captchaId.Response = resp.Split('|')[1]; | |
return captchaId; | |
} | |
// apparently will only be sent after 90 seconds is up | |
else if (resp == "ERROR_CAPTCHA_UNSOLVABLE") | |
{ | |
return captchaId; | |
} | |
} | |
} | |
catch (Exception ex) | |
{ | |
#if DEBUG | |
Debug.WriteLine("PollCaptchaID {0}: {1}", attemptsMax, ex); | |
#endif | |
} | |
// Change to what you like, 2captcha are pretty slow, so expect some heavy waiting | |
Thread.Sleep(5000); | |
} | |
return captchaId; | |
} | |
private CaptchaResult GetCaptchaID() | |
{ | |
NameValueCollection nvc = new NameValueCollection(); | |
string formattedProxy = string.Format("{0}:{1}", AccessProxy.Address.DnsSafeHost, AccessProxy.Address.Port); | |
nvc.Add("key", APIKey); | |
nvc.Add("method", "userrecaptcha"); | |
nvc.Add("googlekey", SiteKey); | |
nvc.Add("proxy", formattedProxy); | |
nvc.Add("proxytype", "http"); | |
nvc.Add("pageurl", SiteURL); | |
int attemptsMax = MaxSubmitTries; | |
// Guess what, you're mad and I'm not | |
// People prefer a while loop over goto's these days, idk why | |
// They're all the same in the end | |
while ((attemptsMax--) > 0) | |
{ | |
try | |
{ | |
using (WebClient wc = new WebClient()) | |
{ | |
string resp = Encoding.UTF8.GetString(wc.UploadValues(string.Format("{0}", IN_URL), nvc)); | |
if (resp.StartsWith("OK|")) | |
{ | |
return new CaptchaResult(null, resp.Split('|')[1], APIKey); | |
} | |
else | |
{ | |
return null; | |
} | |
} | |
} | |
catch (Exception ex) | |
{ | |
#if DEBUG | |
Debug.WriteLine("GetCaptchaID: {0}", ex); | |
#endif | |
} | |
Thread.Sleep(1500); | |
} | |
return null; | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment