using System; using System.IO; using System.Net; using System.Text; using System.Threading; /// /// ============================================================= /// 极验识别 Demo (C#版) /// /// 功能说明: /// 提交极验验证码识别任务(支持三代/四代) /// 极验识别为异步流程:先提交任务获取resultid,再轮询查询结果 /// /// 使用方法: /// 1. 将下方的配置参数替换为你自己的值 /// 2. 编译运行:csc /out:RecognizeGeetest.exe RecognizeGeetest.cs && RecognizeGeetest.exe /// ============================================================= /// class RecognizeGeetest { // ======================== 配置区域(请替换为你自己的参数)======================== // 用户密钥,登录平台后获取 static string APPKEY = "你的appkey"; // 极验gt值(三代为gt值,四代为captcha_id值) static string GT = "你获取到的gt值"; // challenge值(三代必填,每次只能使用一次;四代无需传此参数,留空即可) static string CHALLENGE = ""; // 项目类型(请参照项目价格表,不同类型对应不同的itemid) static int ITEM_ID = 0; // 验证码所在的页面URL(可选,部分网站需要填写) static string REFERER = ""; // 可选参数:代理IP(格式示例:http://IP:端口,若需白名单支持请联系客服。http://账号:密码@proxy.com:8080 或 socks5://127.0.0.1:9888) static string PROXY = ""; // 可选参数:开发者密钥(如果有的话填写) static string DEVKEY = ""; // 可选参数:SDK版本(特殊版本为2,默认为1) static string SDK = ""; // 可选参数:对接模式(按次计费:0,包月计费:1,默认为0。包月用户必填) static string GIVEN = ""; // 可选参数:特殊网站极验域名(如api-na.geetest.com,不要带http://和/,只需域名) static string HOST_PARAM = ""; // 可选参数:User-Agent(适用于某些检验UA的网站,只支持传入安卓ua) static string USER_AGENT = ""; // =============================================================================== // API基础地址 static string API_BASE = "http://api.ttocr.com/api"; // 轮询配置 static int POLL_INTERVAL = 2000; // 轮询间隔(毫秒),不得低于1秒 static int MAX_POLL_TIME = 60000; // 最大等待时间(毫秒) /// /// 发送POST请求(表单数据) /// static string HttpPost(string url, string postData) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.Timeout = 30000; byte[] data = Encoding.UTF8.GetBytes(postData); request.ContentLength = data.Length; using (Stream stream = request.GetRequestStream()) { stream.Write(data, 0, data.Length); } using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { return reader.ReadToEnd(); } } static void Main(string[] args) { Console.OutputEncoding = Encoding.UTF8; Console.WriteLine(new string('*', 60)); Console.WriteLine(" 极验识别 Demo (C#版)"); Console.WriteLine(new string('*', 60)); if (APPKEY == "你的appkey") { Console.WriteLine("\n[错误] 请先在代码顶部的配置区域填写你的 APPKEY"); Environment.Exit(1); } if (GT == "你获取到的gt值") { Console.WriteLine("\n[错误] 请先在代码顶部的配置区域填写 GT 值"); Environment.Exit(1); } if (ITEM_ID == 0) { Console.WriteLine("\n[错误] 请先在代码顶部的配置区域填写 ITEM_ID(项目类型)"); Environment.Exit(1); } try { // ========== 步骤1:提交极验识别任务 ========== Console.WriteLine(new string('=', 50)); Console.WriteLine("[提交任务] 正在提交极验识别任务..."); Console.WriteLine(new string('=', 50)); StringBuilder postData = new StringBuilder(); postData.Append("appkey=").Append(Uri.EscapeDataString(APPKEY)); postData.Append(">=").Append(Uri.EscapeDataString(GT)); postData.Append("&itemid=").Append(ITEM_ID); if (!string.IsNullOrEmpty(CHALLENGE)) postData.Append("&challenge=").Append(Uri.EscapeDataString(CHALLENGE)); if (!string.IsNullOrEmpty(REFERER)) postData.Append("&referer=").Append(Uri.EscapeDataString(REFERER)); if (!string.IsNullOrEmpty(PROXY)) postData.Append("&proxy=").Append(Uri.EscapeDataString(PROXY)); if (!string.IsNullOrEmpty(DEVKEY)) postData.Append("&devkey=").Append(Uri.EscapeDataString(DEVKEY)); if (!string.IsNullOrEmpty(SDK)) postData.Append("&sdk=").Append(Uri.EscapeDataString(SDK)); if (!string.IsNullOrEmpty(GIVEN)) postData.Append("&given=").Append(Uri.EscapeDataString(GIVEN)); if (!string.IsNullOrEmpty(HOST_PARAM)) postData.Append("&host=").Append(Uri.EscapeDataString(HOST_PARAM)); if (!string.IsNullOrEmpty(USER_AGENT)) postData.Append("&userAgent=").Append(Uri.EscapeDataString(USER_AGENT)); Console.WriteLine("[请求参数] gt=" + GT); Console.WriteLine("[请求参数] itemid=" + ITEM_ID); string submitUrl = API_BASE + "/recognize"; string submitResult = HttpPost(submitUrl, postData.ToString()); Console.WriteLine("[提交响应] " + submitResult); // 简单解析resultid(无需JSON库) string resultid = null; if (submitResult.Contains("\"status\":1") || submitResult.Contains("\"status\": 1")) { int ridStart = submitResult.IndexOf("\"resultid\":"); if (ridStart >= 0) { int valStart = submitResult.IndexOf("\"", ridStart + 11) + 1; int valEnd = submitResult.IndexOf("\"", valStart); resultid = submitResult.Substring(valStart, valEnd - valStart); Console.WriteLine("[成功] 任务提交成功!resultid=" + resultid); } } else { Console.WriteLine("[失败] 任务提交失败"); } if (string.IsNullOrEmpty(resultid)) { Console.WriteLine("[失败] 未获取到resultid,请检查参数配置"); Environment.Exit(1); } // ========== 步骤2:轮询查询识别结果 ========== Console.WriteLine("\n" + new string('=', 50)); Console.WriteLine("[查询结果] 正在轮询识别结果..."); Console.WriteLine("[查询结果] 轮询间隔:" + (POLL_INTERVAL / 1000) + "秒,最大等待:" + (MAX_POLL_TIME / 1000) + "秒"); Console.WriteLine(new string('=', 50)); string queryUrl = API_BASE + "/results"; long startTime = Environment.TickCount; while (true) { long elapsed = Environment.TickCount - startTime; if (elapsed > MAX_POLL_TIME) { Console.WriteLine("[超时] 已等待" + (MAX_POLL_TIME / 1000) + "秒,识别超时,请稍后重试"); break; } Thread.Sleep(POLL_INTERVAL); string queryData = "appkey=" + Uri.EscapeDataString(APPKEY) + "&resultid=" + Uri.EscapeDataString(resultid); string queryResult = HttpPost(queryUrl, queryData); elapsed = Environment.TickCount - startTime; if (queryResult.Contains("\"status\":1") || queryResult.Contains("\"status\": 1")) { Console.WriteLine("\n[成功] 识别成功!"); Console.WriteLine("[完整响应] " + queryResult); break; } else { Console.WriteLine("[等待中] 第" + (elapsed / 1000) + "秒 - 正在识别中..."); } } } catch (Exception e) { Console.WriteLine("[异常] 网络请求出错:" + e.Message); } Console.WriteLine("\n" + new string('=', 50)); Console.WriteLine("[完成] 识别执行完毕"); Console.WriteLine(new string('=', 50)); } }