Captcha bypass tutorials

How to bypass captcha in C#

How to bypass captcha in C# using captcha solving service

This guide walks you through bypassing captchas in C# using the 2Captcha API and the 2captcha-csharp library. You will learn how to smoothly integrate solutions for tasks like automating captcha handling in C# and bypassing captcha protections.


Why bypass captchas?

Understanding the benefits of solving captchas, especially for automation, helps you optimize your workflows. Captchas protect sites from bots, but with tools like the 2Captcha API, developers can handle them programmatically.

In web scraping and automation, captchas act as a gate to ensure human interaction. While their goal is to block bots, tools like the 2Captcha API let developers work around these checks. This guide will be your companion for solving captchas with C#.

What you need

  1. Basic C# programming knowledge.
  2. A registered 2Captcha account with a valid API key.
  3. .NET SDK version 5.0 or higher installed.
  4. Access to the 2captcha-csharp library.

Step by step implementation

1. Add the required library

The 2captcha-csharp library is available via NuGet, making it easy to add to your project:

bash Copy
dotnet add package TwoCaptcha

Installing TwoCaptcha via NuGet is a key step for efficient captcha solving in C#.

2. Get your API key

To get started, grab your API key:

  1. Log in to your 2Captcha account.
  2. Go to the API Key page.
  3. Copy your personal API key for use in your project.

3. Write the code

Here is a practical example using the library to solve a Geetest v4 captcha with proxy support and error handling:

csharp Copy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using RestSharp;

class GenericCaptchaSolver
{
    private static readonly string ApiKey = Environment.GetEnvironmentVariable("APIKEY");
    private static readonly string Proxy = "login:password@ip:port";
    private static readonly string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36";
    private static readonly string TargetUrl = "https://example.com/target-page";
    private static readonly string CaptchaId = "your_captcha_id_here";
    private static readonly string CreateEndpoint = "https://2captcha.cn/create.php";
    private static readonly string ResultEndpoint = "https://2captcha.cn/res.php";

    static async Task Main(string[] args)
    {
        try
        {
            await SolveCaptchaAsync();
        }
        catch (CaptchaException ex)
        {
            Console.WriteLine("Captcha error: " + ex.Message);
            HandleCaptchaError(ex.ErrorCode);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Unexpected error: " + ex.Message);
        }
    }

    static async Task SolveCaptchaAsync()
    {
        var options = new ChromeOptions();
        options.AddArgument("--user-agent=" + UserAgent);
        options.AddArgument("--incognito");
        options.AddArgument("--disable-dev-shm-usage");
        options.AddArgument("--no-sandbox");

        SetupProxy(options, Proxy);

        using var driver = new ChromeDriver(options);
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);

        try
        {
            driver.Navigate().GoToUrl(TargetUrl);
            await Task.Delay(3000);

            var captchaVisible = driver.FindElements(By.CssSelector("body > div.firewall-container > h2")).Any();
            if (!captchaVisible)
            {
                Console.WriteLine("Captcha not visible");
                return;
            }

            Console.WriteLine("Captcha visible, solving...");
            var result = await SolveGeetestV4Async(driver.Url, Proxy);

            var code = result["code"].ToString();
            var lotNumber = ExtractValue(code, "lot_number");
            var passToken = ExtractValue(code, "pass_token");
            var genTime = ExtractValue(code, "gen_time");
            var captchaOutput = ExtractValue(code, "captcha_output");

            var cookies = driver.Manage().Cookies.AllCookies;
            var cookieDict = cookies.ToDictionary(c => c.Name, c => c.Value);

            var verificationResult = await SendVerificationRequestAsync(
                cookieDict.GetValueOrDefault("srv_id", ""),
                cookieDict.GetValueOrDefault("u", ""),
                cookieDict.GetValueOrDefault("v", ""),
                lotNumber, passToken, genTime, captchaOutput
            );

            if (verificationResult.Contains("\"verified\":true"))
            {
                Console.WriteLine("Captcha passed");
                driver.Navigate().Refresh();
                await Task.Delay(15000);
            }
            else
            {
                throw new CaptchaException("Verification failed", "ERROR_CAPTCHA_UNSOLVABLE");
            }
        }
        finally
        {
            driver.Quit();
        }
    }

    static void SetupProxy(ChromeOptions options, string proxy)
    {
        var parts = proxy.Split('@');
        var endpoint = parts[1].Split(':');
        options.AddArgument("--proxy-server=" + endpoint[0] + ":" + endpoint[1]);
    }

    static string ExtractValue(string json, string key)
    {
        var pattern = "\"" + key + "\":\"([^\"]+)\"";
        var match = Regex.Match(json, pattern);
        return match.Success ? match.Groups[1].Value : string.Empty;
    }

    static async Task<JObject> SolveGeetestV4Async(string url, string proxy)
    {
        var proxyParts = proxy.Split('@');
        var auth = proxyParts[0].Split(':');
        var endpoint = proxyParts[1].Split(':');

        var postData = new Dictionary<string, string>
        {
            { "key", ApiKey },
            { "method", "geetest_v4" },
            { "captcha_id", CaptchaId },
            { "pageurl", url },
            { "proxy", endpoint[0] },
            { "proxyport", endpoint[1] },
            { "proxytype", "HTTPS" },
            { "proxyuser", auth[0] },
            { "proxypass", auth[1] },
            { "json", "1" }
        };

        using var client = new HttpClient();
        var content = new FormUrlEncodedContent(postData);
        var response = await client.PostAsync(CreateEndpoint, content);
        var responseText = await response.Content.ReadAsStringAsync();
        var result = JObject.Parse(responseText);

        if (result["status"]?.ToString() != "1")
        {
            var error = result["request"]?.ToString() ?? "Unknown error";
            throw new CaptchaException(error, error);
        }

        var taskId = result["request"]?.ToString();
        if (string.IsNullOrEmpty(taskId))
            throw new CaptchaException("Empty task ID", "ERROR_TASK_ABSENT");

        for (int i = 0; i < 60; i++)
        {
            await Task.Delay(5000);
            var getResult = await client.GetAsync(ResultEndpoint + "?key=" + ApiKey + "&action=get&id=" + taskId + "&json=1");
            var getResultText = await getResult.Content.ReadAsStringAsync();
            var resultData = JObject.Parse(getResultText);

            if (resultData["status"]?.ToString() == "1")
                return resultData;

            var request = resultData["request"]?.ToString();
            if (request == "CAPCHA_NOT_READY")
                continue;

            throw new CaptchaException(request ?? "Unknown error", request ?? "ERROR_BAD_PARAMETERS");
        }

        throw new TimeoutException("Captcha solving timeout");
    }

    static async Task<string> SendVerificationRequestAsync(string srvId, string u, string v,
        string lotNumber, string passToken, string genTime, string captchaOutput)
    {
        var client = new RestClient("https://example.com/web/1/firewallCaptcha/verify");
        var request = new RestRequest(Method.Post);

        request.AddHeader("accept", "*/*");
        request.AddHeader("accept-language", "en");
        request.AddHeader("content-type", "application/json");
        request.AddHeader("origin", "https://example.com");
        request.AddHeader("referer", TargetUrl);
        request.AddHeader("user-agent", UserAgent);

        request.AddCookie("srv_id", srvId);
        request.AddCookie("u", u);
        request.AddCookie("v", v);

        var jsonBody = new
        {
            captcha = "",
            hCaptchaResponse = "",
            captcha_id = CaptchaId,
            lot_number = lotNumber,
            pass_token = passToken,
            gen_time = genTime,
            captcha_output = captchaOutput
        };

        request.AddJsonBody(jsonBody);
        var response = await client.ExecuteAsync(request);
        return response.Content;
    }

    static void HandleCaptchaError(string errorCode)
    {
        Console.WriteLine("Error code: " + errorCode);
    }
}

public class CaptchaException : Exception
{
    public string ErrorCode { get; }
    public CaptchaException(string message, string errorCode) : base(message)
    {
        ErrorCode = errorCode;
    }
}

4. Prepare the captcha image

Make sure the captcha image you want to solve is saved locally and accessible. Update the captchaImagePath variable in your script with the path to your file.

5. Run the program

Run your C# script using the .NET CLI or your favorite IDE to execute the solution.

bash Copy
dotnet run

After execution, the solved captcha text will appear in the console.


How it works

  1. API initialization: The TwoCaptcha library is created using your API key, connecting your app to the service.
  2. Image upload: You specify the path to the captcha image, which the library uploads for processing.
  3. Captcha solving: The API processes the image and returns the decoded text.
  4. Output: The decoded captcha text is displayed, ready to use in your workflow.

Tips for smooth integration

  • Protect your credentials: Use environment variables or secure config files to store sensitive API keys.
  • Monitor API usage: Regularly check your 2Captcha account balance to avoid service interruptions.
  • Respect API limits: Add pauses between requests to stay within 2Captcha limits and avoid account restrictions.

Debugging block: error codes and meanings

Error code Description
ERROR_NO_SLOT_AVAILABLE Bid too low or queue full. Try again later or increase your bid
ERROR_PAGEURL Missing or invalid pageurl format. Provide a correct page URL
ERROR_CAPTCHA_UNSOLVABLE Captcha could not be solved. Funds are automatically refunded to your balance
ERROR_TASK_ABSENT Missing task parameter in createTask call. Check your request structure
ERROR_BAD_PARAMETERS Missing required parameters or invalid request format. Review the documentation
ERROR_BAD_PROXY Invalid proxy parameters or connection failed. Check proxy:port:username:password format

Wrapping up

Integrating the 2Captcha API into C# apps lets you automate captcha solving, which greatly boosts efficiency for web scraping and automation tasks. By following this guide, you can successfully add captcha handling to your projects, streamline your workflows, and cut down time spent on these tasks. This solution opens new possibilities for automation, making your apps more productive and competitive.