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));
}
}