C#으로 reCAPTCHA Enterprise 해결하기

작성: solvethree읽는 데 2분

C#에서 solvethree를 직접 호출할 수 있습니다. 아래 예제는 reCAPTCHA v3 Enterprise 토큰을 요청하고, 작업이 끝날 때까지 상태를 확인하며, 해결에 실패하면 중단합니다.

이 페이지의 내용

실행 전 준비

.NET 8+를 사용하세요. 추가 NuGet 패키지는 필요하지 않습니다.

  • 콘솔에서 대상 호스트 이름에 대한 활성 사이트 프로필을 생성하세요. 사이트 프로필 설정을 참고하세요.
  • SOLVETHREE_API_KEY를 워크스페이스 API 키로, SOLVETHREE_PROXY를 HTTP(S) 프록시 URL로 설정하세요.
  • accounts.example.com과 login을 호스트 이름과 페이지에서 사용하는 액션으로 바꾸세요. site에는 스킴이나 경로 없이 호스트 이름을 사용하세요.

작업 생성 및 결과 대기

dotnet new console로 .NET 콘솔 프로젝트를 생성하고, Program.cs를 이 코드로 바꾼 다음 dotnet run을 실행하세요.

C# · Program.cs (.NET 8+)
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json.Nodes;

var key = Environment.GetEnvironmentVariable("SOLVETHREE_API_KEY")
    ?? throw new Exception("Set SOLVETHREE_API_KEY");
var proxy = Environment.GetEnvironmentVariable("SOLVETHREE_PROXY")
    ?? throw new Exception("Set SOLVETHREE_PROXY");
using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", key);
using var deadline = new CancellationTokenSource(TimeSpan.FromSeconds(180));

async Task<JsonObject> Api(HttpMethod method, string path, JsonObject? body = null)
{
    using var request = new HttpRequestMessage(method, "https://api.solvethree.com/v1" + path);
    if (body is not null)
        request.Content = new StringContent(body.ToJsonString(), Encoding.UTF8, "application/json");
    using var response = await http.SendAsync(request, deadline.Token);
    response.EnsureSuccessStatusCode();
    return JsonNode.Parse(await response.Content.ReadAsStringAsync(deadline.Token))!.AsObject();
}

var requestId = Guid.NewGuid().ToString(); // Save with these inputs for recovery.
var input = new JsonObject {
    ["site"] = "accounts.example.com", ["action"] = "login",
    ["proxy"] = proxy, ["requestId"] = requestId
};
var task = await Api(HttpMethod.Post, "/tasks?waitMs=0", input);
while (task["status"]!.GetValue<string>() is "pending" or "solving")
{
    var id = Uri.EscapeDataString(task["id"]!.GetValue<string>());
    task = await Api(HttpMethod.Get, "/tasks/" + id + "?waitMs=15000");
    if (task["status"]!.GetValue<string>() is "pending" or "solving")
        await Task.Delay(1000, deadline.Token);
}
if (task["status"]!.GetValue<string>() != "ready")
    throw new Exception("Task failed: " + task["errorCode"]?.GetValue<string>()
        + ": " + task["error"]?.GetValue<string>());
var solution = task["solution"]!.AsObject();
// Use solution["token"], ["userAgent"] and ["secChUa"] with the original proxy.
Console.WriteLine("Ready task: " + task["id"]!.GetValue<string>());

POST는 waitMs=0을 사용해 작업을 즉시 반환합니다. 이후 각 GET은 업데이트를 최대 15초 동안 기다립니다. 루프는 pending 또는 solving 상태에서 계속되며, ready 또는 failed 상태에서 중단됩니다.

요청의 기본값은 Enterprise v3입니다. 일반 v3를 사용하려면 recaptchaType: v3를 추가하세요. reCAPTCHA 작업 본문에 type과 url을 넣지 마세요.

애플리케이션에서 토큰 사용하기

토큰은 solution["token"]!.GetValue<string>()입니다. 프로그램이 출력하는 작업 ID는 작업 조회용입니다. 애플리케이션의 CAPTCHA 필드에는 토큰 값을 사용하세요.

대상 요청의 User-Agent 및 sec-ch-ua 헤더에 사용할 solution["userAgent"]와 solution["secChUa"]를 읽으세요.

해결에 사용한 것과 동일한 프록시를 통해 해당 요청을 보내세요. 그런 다음 애플리케이션의 응답을 확인하세요. 토큰이 생성되었다고 해서 대상이 요청을 수락했다는 뜻은 아닙니다.

요청 실패 시

실패한 작업에는 errorCode와 error가 포함되며, 예제는 실행을 중단하고 이를 보고합니다. 실패한 해결 건은 환불됩니다. 401이나 402 같은 HTTP 오류는 별도의 요청 문제이므로, 재시도하기 전에 API 오류 레퍼런스를 확인하세요.

시간 초과나 프로세스 재시작 후 복구해야 한다면 requestId와 정확한 작업 입력값을 보관하세요. 작업 ID가 있으면 해당 작업을 폴링하세요. 없다면 동일한 requestId로 원래 입력값을 다시 보내세요. 단순히 프로그램을 재시작하면 다른 ID가 생성되어 추가로 과금되는 해결 작업이 만들어질 수 있습니다.

호출 측은 기한이 지나면 대기를 중단하지만, 이미 생성된 작업이 취소되는 것은 아닙니다. 전체 절차는 폴링 및 시간 초과 복구를 참고하세요.

첫 작업을 실행하세요.

워크스페이스 크레딧 $5로 시작하세요.

워크스페이스 만들기
C#으로 reCAPTCHA Enterprise 해결하기 · solvethree