Эта статья была полезной?
Как обойти и решить капчу на C#

Это руководство подробно описывает процесс обхода капчи в C# с использованием API RuCaptcha и библиотеки 2captcha-csharp. Вы узнаете, как эффективно интегрировать решения для задач, таких как автоматизация капчи в C# и обход капчи в C#.
Зачем обходить капчи?
Понимание преимуществ решения капчи, особенно в контексте автоматизации, поможет оптимизировать рабочие процессы. Капчи служат защитой от ботов, но с помощью инструментов, таких как API RuCaptcha, разработчики могут программно их обходить.
В мире веб-скрейпинга и автоматизации капчи являются барьером, обеспечивающим взаимодействие с человеком. Хотя их цель — отпугивать ботов, инструменты, такие как API RuCaptcha, позволяют разработчикам преодолевать эти препятствия. Это руководство станет вашим путеводителем в решении капчи с использованием C#.
Что потребуется
- Базовые знания программирования на C#.
- Зарегистрированный аккаунт RuCaptcha с действительным API-ключом.
- Установленный .NET SDK (версии 5.0 или выше).
- Доступ к библиотеке
2captcha-csharp.
Пошаговая реализация
1. Добавьте необходимую библиотеку
Библиотека 2captcha-csharp доступна через NuGet, что упрощает её добавление в проект:
bash
dotnet add package TwoCaptcha
Установка TwoCaptcha через NuGet — важный шаг для обеспечения эффективного решения капчи в C#.
2. Получите ваш API-ключ
Чтобы начать, получите ваш API-ключ:
- Войдите в свою учетную запись RuCaptcha.
- Перейдите на страницу API Key.
- Скопируйте ваш персональный API-ключ для использования в проекте.
3. Напишите код
Ниже приведен практический пример использования библиотеки для решения капчи типа Geetest v4 с прокси и обработкой ошибок:
csharp
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://rucaptcha.com/create.php";
private static readonly string ResultEndpoint = "https://rucaptcha.com/res.php";
static async Task Main(string[] args)
{
try
{
await SolveCaptchaAsync();
}
catch (CaptchaException ex)
{
Console.WriteLine("Ошибка капчи: " + ex.Message);
HandleCaptchaError(ex.ErrorCode);
}
catch (Exception ex)
{
Console.WriteLine("Непредвиденная ошибка: " + 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("Код ошибки: " + errorCode);
}
}
public class CaptchaException : Exception
{
public string ErrorCode { get; }
public CaptchaException(string message, string errorCode) : base(message)
{
ErrorCode = errorCode;
}
}
4. Подготовьте изображение капчи
Убедитесь, что изображение капчи, которое вы хотите решить, сохранено локально и доступно. Обновите переменную captchaImagePath в вашем скрипте, указав путь к файлу.
5. Запустите программу
Запустите ваш скрипт на C# с использованием .NET CLI или вашей любимой IDE, чтобы эффективно выполнить решение.
bash
dotnet run
После выполнения решённый текст капчи отобразится в консоли.
Подробности процесса
- Инициализация API: Библиотека
TwoCaptchaсоздаётся с использованием API-ключа, связывая ваше приложение с сервисом. - Загрузка изображения: Указывается путь к изображению капчи, которое библиотека загружает для обработки.
- Решение капчи: API обрабатывает изображение и возвращает декодированный текст.
- Вывод: Декодированный текст капчи отображается, готовый к интеграции в ваш рабочий процесс.
Советы для бесшовной интеграции
- Защитите ваши учетные данные: Используйте переменные окружения или защищённые конфигурационные файлы для хранения чувствительных API-ключей.
- Мониторинг использования API: Регулярно проверяйте баланс вашего аккаунта на RuCaptcha, чтобы избежать перебоев в работе.
- Следите за лимитами API: Делайте паузы между запросами, чтобы оставаться в пределах лимитов RuCaptcha и избежать ограничений аккаунта.
Блок отладки: коды ошибок и их значения
| Код ошибки | Описание |
|---|---|
| ERROR_NO_SLOT_AVAILABLE | Ставка слишком низкая или очередь переполнена. Попробуйте позже или увеличьте ставку |
| ERROR_PAGEURL | Отсутствует или неверный формат pageurl. Укажите корректный URL страницы |
| ERROR_CAPTCHA_UNSOLVABLE | Капчу не удалось решить. Средства автоматически возвращены на баланс |
| ERROR_TASK_ABSENT | Отсутствует параметр task в вызове createTask. Проверьте структуру запроса |
| ERROR_BAD_PARAMETERS | Отсутствуют обязательные параметры или неверный формат запроса. Сверьтесь с документацией |
| ERROR_BAD_PROXY | Неверные параметры прокси или не удаётся подключиться. Проверьте формат proxy:port:username:password |
Заключение
Интеграция API RuCaptcha в приложения на C# позволяет автоматизировать процесс решения капч, что значительно повышает эффективность задач, связанных с веб-скрейпингом и автоматизацией. Следуя данному руководству, вы сможете успешно внедрить решение капч в свои проекты, оптимизировать рабочие процессы и минимизировать временные затраты на обработку подобных задач. Это решение открывает новые возможности для автоматизации, делая ваши приложения более производительными и конкурентоспособными.