如何使用 C# 解决 Cloudflare Turnstile CAPTCHA 挑战
处理 CAPTCHA 挑战的复杂性可能是一项艰巨的任务,尤其是在涉及 Cloudflare 的 Turnstile 时。作为一名经验丰富的开发人员,我多年来遇到了许多 CAPTCHA 系统,但 Cloudflare Turnstile 由于其旨在阻止自动化系统的复杂算法,提出了独特的挑战。在本指南中,我将引导您使用 C# 处理 Cloudflare Turnstile CAPTCHA 挑战,为您提供实用见解和技术,以增强您的自动化工作。
目录
- Cloudflare Turnstile 简介
- 设置 C# 开发环境
- 下载并安装 .NET
- 为 C# 开发配置 VS Code
- 获取 API 使用先决条件
- 注册 CapSolver
- 获取 Turnstile 的 SiteKey
- 使用 CapSolver API 获取 Turnstile 令牌
- 完整代码示例
- 错误处理和故障排除
- 请求失败错误
- 代码解释
- 结论
了解 Cloudflare Turnstile
Cloudflare Turnstile 是一种高级 CAPTCHA 系统,旨在保护网站免受自动化机器人的攻击,同时确保合法用户受到最小的阻碍。与传统的 CAPTCHA(通常涉及解决谜题或识别物体)不同,Turnstile 通过更加细致入微的方式运作。它分析用户行为和各种网络互动,以确定访问者是人类还是机器人。
Turnstile 使用一系列信号(包括鼠标移动、点击模式和互动时间)来生成对自动化系统难以解决的挑战。这使其成为网站安全的强大工具,但也成为自动化的一大障碍。
附加代码
索取 奖励代码 以获得顶级验证码解决方案;CapSolver: WEBS。兑换后,每次充值后您将获得额外的 5% 奖励,无限次
设置 C# 开发环境
1. 下载并安装 .NET
- 访问 此页面 下载 .NET。
- 按照提供的说明安装 .NET,以适合您的操作系统。
2. 为 C# 开发配置 VS Code
- 为 VS Code 安装 C# 扩展。
- 在 VS Code 中,在扩展市场中搜索“C#”,然后安装微软的官方插件。
- 此扩展提供了 IntelliSense 和代码格式化等功能,使 C# 开发更容易。
- 安装用于处理 JSON 数据的 JSON 解析包
Newtonsoft.Json
。- 您可以使用以下命令通过 NuGet 安装此包:
dotnet add package Newtonsoft.Json
- 您可以使用以下命令通过 NuGet 安装此包:
获取 API 使用先决条件
1. 注册 CapSolver
- 在 CapSolver 上创建一个帐户以访问他们的 API 服务。
- 注册后,您将收到一个 API 密钥,该密钥是访问 CapSolver 的 CAPTCHA 解决服务的必要条件。
2. 获取 Turnstile 的 SiteKey
- 对于 Cloudflare Turnstile CAPTCHA 挑战,获取目标网站的
siteKey
至关重要。siteKey
是使用解码 API 和解决 CAPTCHA 所必需的。 - 您可以使用 CapSolver 扩展 提取
siteKey
,该扩展简化了此过程。
使用 CapSolver API 获取 Turnstile 令牌
以下是与 CapSolver API 交互、请求 CAPTCHA 解决并检索 Turnstile 令牌的代码。
public static async Task<string> CallCapsolver()
{
// // 发送 GET 请求
// var todoItem = await GetTodoItemAsync(API_URL);
// Console.WriteLine("GET 请求结果:");
// Console.WriteLine(todoItem);
var data = new
{
clientKey = CAPSOLVER_API_KEY,
task = new
{
type = "AntiTurnstileTaskProxyLess",
websiteURL = PAGE_URL,
websiteKey = SITE_KEY,
metadata = new { action = "login" }
}
};
// 发送 POST 请求
var response = await PostTodoItemAsync("https://api.capsolver.com/createTask", data);
Console.WriteLine("POST 请求结果:");
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
JObject taskResp = JsonConvert.DeserializeObject<JObject>(responseString);
var taskId = taskResp["taskId"].ToString();
if (string.IsNullOrEmpty(taskId))
{
Console.WriteLine("未收到任务 ID。");
return "";
}
Console.WriteLine($"创建的任务 ID:{taskId}");
while (true)
{
await Task.Delay(1000); // 休眠 1 秒
var resultData = new
{
clientKey = CAPSOLVER_API_KEY,
taskId = taskId
};
// content = new StringContent(JsonConvert.SerializeObject(data), System.Text.Encoding.UTF8, "application/json");
// response = await httpClient.PostAsync(uri, content);
response = await PostTodoItemAsync("https://api.capsolver.com/getTaskResult", resultData);
responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
if (!response.IsSuccessStatusCode)
{
Console.WriteLine($"获取任务结果失败:{responseString}");
return "";
}
taskResp = JsonConvert.DeserializeObject<JObject>(responseString);
Console.WriteLine(taskResp);
var status = taskResp["status"].ToString();
if (status == "ready")
{
Console.WriteLine("成功 => " + responseString);
return taskResp["solution"]["token"].ToString();
}
if (status == "failed")
{
Console.WriteLine("失败! => " + responseString);
return "";
}
}
}
完整代码示例
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace HttpExample
{
public class Program
{
private const string CAPSOLVER_API_KEY = "CAI-xxxxxxxxxxxxxxxxxxx";
private const string PAGE_URL = "https://dash.cloudflare.com/login";
private const string SITE_KEY = "0x4AAAAAAAJel0iaAR3mgkjp";
public static async Task Main(string[] args)
{
var token = await CallCapsolver();
Console.WriteLine($"token: {token}");
await Login(token);
}
public static async Task<string> CallCapsolver()
{
// // 发送 GET 请求
// var todoItem = await GetTodoItemAsync(API_URL);
// Console.WriteLine("GET 请求结果:");
// Console.WriteLine(todoItem);
var data = new
{
clientKey = CAPSOLVER_API_KEY,
task = new
{
type = "AntiTurnstileTaskProxyLess",
websiteURL = PAGE_URL,
websiteKey = SITE_KEY,
metadata = new { action = "login" }
}
};
// 发送 POST 请求
var response = await PostTodoItemAsync("https://api.capsolver.com/createTask", data);
Console.WriteLine("POST 请求结果:");
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
JObject taskResp = JsonConvert.DeserializeObject<JObject>(responseString);
var taskId = taskResp["taskId"].ToString();
if (string.IsNullOrEmpty(taskId))
{
Console.WriteLine("未收到任务 ID。");
return "";
}
Console.WriteLine($"创建的任务 ID:{taskId}");
while (true)
{
await Task.Delay(1000); // 休眠 1 秒
var resultData = new
{
clientKey = CAPSOLVER_API_KEY,
taskId = taskId
};
// content = new StringContent(JsonConvert.SerializeObject(data), System.Text.Encoding.UTF8, "application/json");
// response = await httpClient.PostAsync(uri, content);
response = await PostTodoItemAsync("https://api.capsolver.com/getTaskResult", resultData);
responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
if (!response.IsSuccessStatusCode)
{
Console.WriteLine($"获取任务结果失败:{responseString}");
return "";
}
taskResp = JsonConvert.DeserializeObject<JObject>(responseString);
Console.WriteLine(taskResp);
var status = taskResp["status"].ToString();
if (status == "ready")
{
Console.WriteLine("成功 => " + responseString);
return taskResp["solution"]["token"].ToString();
}
if (status == "failed")
{
Console.WriteLine("失败! => " + responseString);
return "";
}
}
}
public static async Task Login(string token)
{
using var httpClient = new HttpClient();
// 添加请求标头
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Cookie", $"cf_clearance={token}");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Host", "dash.cloudflare.com");
var data = new {
cf_challenge_response = token,
email = "1111111@gmail.com",
password = "123456",
};
var json = JsonConvert.SerializeObject(data);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("https://dash.cloudflare.com/api/v4/login", content);
if (!response.IsSuccessStatusCode)
{
throw new Exception($"请求失败,状态码为 {response.StatusCode}");
}
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
}
private static async Task<HttpResponseMessage> GetTodoItemAsync(string url)
{
using var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
if (!response.IsSuccessStatusCode)
{
throw new Exception($"请求失败,状态码为 {response.StatusCode}");
}
// var responseString = await response.Content.ReadAsStringAsync();
return response;
}
private static async Task<HttpResponseMessage> PostTodoItemAsync(string url, object item)
{
using var httpClient = new HttpClient();
var json = JsonConvert.SerializeObject(item);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(url, content);
if (!response.IsSuccessStatusCode)
{
throw new Exception($"请求失败,状态码为 {response.StatusCode}");
}
return response;
}
}
}
错误处理和故障排除
- 请求失败: 如果您遇到“请求失败”错误,请验证 API 密钥和站点密钥是否正确。
- 确保您拥有来自 CapSolver 帐户的有效 API 密钥。
- 仔细检查
siteKey
是否与目标网站上的siteKey
相匹配。
解释
- 设置任务: 在
CallCapsolver
方法中,您定义了任务类型AntiTurnstileTaskProxyLess
、websiteURL
和websiteKey
。这些参数将发送到 CapSolver 以创建 CAPTCHA 解决任务。 - 轮询任务状态: 创建任务后,代码会轮询
getTaskResult
端点以检查任务状态。如果任务已准备就绪,它会检索解决方案(Turnstile 令牌);如果失败,它会返回错误。 - 使用令牌:
Login
方法使用从 CapSolver 收到的令牌对 Cloudflare 保护的网站上的登录请求进行身份验证。
结论
通过遵循本指南,您将能够使用 C# 处理解决 Cloudflare Turnstile CAPTCHA 挑战的复杂性。CapSolver 的 API 提供了一种可靠且高效的方式来自动化此过程,从而提高您的自动化能力。如需更多信息和更新,请访问 CapSolver。
关于合规性的说明
重要提示: 在进行网络抓取时,务必遵守法律和道德准则。始终确保您拥有抓取目标网站的权限,并尊重网站的
robots.txt
文件和服务条款。CapSolver 坚决反对将我们的服务用于任何不合规的活动。未经授权使用自动化工具绕过 CAPTCHA 会导致法律后果。确保您的抓取活动符合所有适用的法律法规,以避免潜在问题。