文档中心 / 极验

极验对接示例

分组极验 入口返回首页

极验对接示例支持直接在线查看、复制和下载源码,无需再下载压缩包。

对接示例

按语言环境展开查看代码,支持直接复制和下载源码。

PHP

共 2 个示例,按接口动作拆分。

该语言注意事项

跟随当前语言展示
  • =============================================================== 极验识别 对接示例 - PHP版 使用说明 =============================================================== 【环境准备】 1. 安装 PHP 7.0 或更高版本 下载地址:https://www.php.net/downloads Windows用户推荐下载 Thread Safe 版本 验证安装:php -v 2. 确保启用 curl 扩展 编辑 php.ini,去掉 extension=curl 前面的分号 验证:php -m | findstr curl(Windows) 验证:php -m | grep curl(Linux/Mac) 【文件说明】 - query_points.php 查询账户剩余点数(余额) - recognize_geetest.php 极验验证码识别(支持三代/四代,异步轮询) 【参数配置】 1. $APPKEY - 用户密钥,登录平台后在个人中心获取 2. $GT - 极验gt值(三代为gt值,四代为captcha_id值),从目标网站抓包获取 3. $CHALLENGE - 三代必填(每次只能用一次),四代留空 4. $ITEM_ID - 项目类型编号,请参照项目价格表选择对应的值 5. $REFERER - 验证码所在页面URL,部分网站需要填写 6. $PROXY - 代理IP(可选) 7. $DEVKEY - 开发者密钥(可选) 【运行方式】 1. 查询点数:php query_points.php 2. 极验识别:php recognize_geetest.php 【极验识别流程说明】 极验识别为异步流程,分两步: 步骤1:提交识别任务 → 返回 resultid 步骤2:使用 resultid 轮询查询结果 → 返回识别数据 脚本已自动实现轮询逻辑(sleep),默认每2秒查询一次,最多等待60秒。 【三代与四代的区别】 - 三代:需要传 gt 和 challenge 参数,返回 validate/seccode - 四代:只需传 gt(即captcha_id),无需 challenge,返回 captchaOutput/lotNumber/passToken/genTime 【常见问题】 1. "Call to undefined function curl_init()" → PHP未启用curl扩展,编辑php.ini启用 extension=curl 2. "'php' 不是内部或外部命令" → PHP未安装或未添加到系统PATH 3. 提交后返回 "识别类型错误" → 检查 $ITEM_ID 是否与你的极验类型匹配 4. 三代 challenge 无效 → challenge 每次只能使用一次,请直接抓包获取 【重要注意事项】 - 查询结果接口每秒不得超过1次,否则会被拉黑IP 10分钟 - 查询点数接口每秒不得超过1次,否则会被拉黑24小时 - APPKEY 属于敏感信息,请勿泄露 - 四代如遇无法通过,captchaOutput中的'='符号需用%3D替换

查询点数

query_points.php

下载源码
query_points.php

PHP

<?php
/**
 * =============================================================
 *   查询账户点数 Demo (PHP版)
 *
 *   功能说明:
 *   查询账户剩余点数(余额)
 *
 *   使用方法:
 *   1. 确保PHP已安装并启用curl扩展
 *   2. 将下方的 APPKEY 替换为你自己的用户密钥
 *   3. 运行脚本:php query_points.php
 * =============================================================
 */

// ======================== 配置区域(请替换为你自己的参数)========================
// 用户密钥,登录平台后获取
$APPKEY = "你的appkey";
// ===============================================================================

// API基础地址
$API_BASE = "http://api.ttocr.com/api";

echo str_repeat("*", 60) . "\n";
echo "  查询账户点数 Demo (PHP版)\n";
echo str_repeat("*", 60) . "\n";

if ($APPKEY === "你的appkey") {
    echo "\n[错误] 请先在脚本顶部的配置区域填写你的 APPKEY\n";
    exit(1);
}

echo str_repeat("=", 50) . "\n";
echo "[查询点数] 正在查询账户剩余点数...\n";
echo str_repeat("=", 50) . "\n";

$url = $API_BASE . "/points?appkey=" . urlencode($APPKEY);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo "[异常] 网络请求出错:" . curl_error($ch) . "\n";
    curl_close($ch);
    exit(1);
}
curl_close($ch);

$result = json_decode($response, true);
if ($result && $result["status"] == 1) {
    echo "[成功] 查询成功!当前可用点数:" . $result["points"] . "\n";
} else {
    echo "[失败] 查询失败,错误信息:" . ($result["msg"] ?? "未知") . "\n";
    echo "[提示] 错误状态码:" . ($result["status"] ?? "未知") . ",请参考错误代码表排查\n";
}
echo "[完整响应] " . json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n";

echo "\n" . str_repeat("=", 50) . "\n";
echo "[完成] 查询执行完毕\n";
echo str_repeat("=", 50) . "\n";
?>

提交识别

recognize_geetest.php

下载源码
recognize_geetest.php

PHP

<?php
/**
 * =============================================================
 *   极验识别 Demo (PHP版)
 *
 *   功能说明:
 *   提交极验验证码识别任务(支持三代/四代)
 *   极验识别为异步流程:先提交任务获取resultid,再轮询查询结果
 *
 *   使用方法:
 *   1. 确保PHP已安装并启用curl扩展
 *   2. 将下方的配置参数替换为你自己的值
 *   3. 运行脚本:php recognize_geetest.php
 * =============================================================
 */

// ======================== 配置区域(请替换为你自己的参数)========================
// 用户密钥,登录平台后获取
$APPKEY = "你的appkey";

// 极验gt值(三代为gt值,四代为captcha_id值)
$GT = "你获取到的gt值";

// challenge值(三代必填,每次只能使用一次;四代无需传此参数,留空即可)
$CHALLENGE = "";

// 项目类型(请参照项目价格表,不同类型对应不同的itemid)
$ITEM_ID = 0;

// 验证码所在的页面URL(可选,部分网站需要填写)
$REFERER = "";

// 可选参数:代理IP(格式示例:http://IP:端口,若需白名单支持请联系客服。http://账号:密码@proxy.com:8080 或 socks5://127.0.0.1:9888)
$PROXY = "";

// 可选参数:开发者密钥(如果有的话填写)
$DEVKEY = "";

// 可选参数:SDK版本(特殊版本为2,默认为1)
$SDK = "";

// 可选参数:对接模式(按次计费:0,包月计费:1,默认为0。包月用户必填)
$GIVEN = "";

// 可选参数:特殊网站极验域名(如api-na.geetest.com,不要带http://和/,只需域名)
$HOST_PARAM = "";

// 可选参数:User-Agent(适用于某些检验UA的网站,只支持传入安卓ua)
$USER_AGENT = "";
// ===============================================================================

// API基础地址
$API_BASE = "http://api.ttocr.com/api";

// 轮询配置
$POLL_INTERVAL = 2;    // 轮询间隔(秒),不得低于1秒
$MAX_POLL_TIME = 60;   // 最大等待时间(秒)

/**
 * 发送POST请求
 */
function httpPost($url, $postData) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    $response = curl_exec($ch);
    if (curl_errno($ch)) {
        $error = curl_error($ch);
        curl_close($ch);
        throw new Exception("网络请求出错:" . $error);
    }
    curl_close($ch);
    return json_decode($response, true);
}

echo str_repeat("*", 60) . "\n";
echo "  极验识别 Demo (PHP版)\n";
echo str_repeat("*", 60) . "\n";

if ($APPKEY === "你的appkey") {
    echo "\n[错误] 请先在脚本顶部的配置区域填写你的 APPKEY\n";
    exit(1);
}
if ($GT === "你获取到的gt值") {
    echo "\n[错误] 请先在脚本顶部的配置区域填写 GT 值\n";
    exit(1);
}
if ($ITEM_ID === 0) {
    echo "\n[错误] 请先在脚本顶部的配置区域填写 ITEM_ID(项目类型)\n";
    exit(1);
}

try {
    // ========== 步骤1:提交极验识别任务 ==========
    echo str_repeat("=", 50) . "\n";
    echo "[提交任务] 正在提交极验识别任务...\n";
    echo str_repeat("=", 50) . "\n";

    $postData = [
        "appkey" => $APPKEY,
        "gt" => $GT,
        "itemid" => $ITEM_ID,
    ];
    if (!empty($CHALLENGE)) { $postData["challenge"] = $CHALLENGE; }
    if (!empty($REFERER)) { $postData["referer"] = $REFERER; }
    if (!empty($PROXY)) { $postData["proxy"] = $PROXY; }
    if (!empty($DEVKEY)) { $postData["devkey"] = $DEVKEY; }
    if (!empty($SDK)) { $postData["sdk"] = $SDK; }
    if (!empty($GIVEN)) { $postData["given"] = $GIVEN; }
    if (!empty($HOST_PARAM)) { $postData["host"] = $HOST_PARAM; }
    if (!empty($USER_AGENT)) { $postData["userAgent"] = $USER_AGENT; }

    echo "[请求参数] gt=" . $GT . "\n";
    echo "[请求参数] itemid=" . $ITEM_ID . "\n";

    $submitResult = httpPost($API_BASE . "/recognize", $postData);
    echo "[提交响应] " . json_encode($submitResult, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n";

    if (!isset($submitResult["status"]) || $submitResult["status"] != 1 || !isset($submitResult["resultid"])) {
        echo "[失败] 任务提交失败,错误信息:" . ($submitResult["msg"] ?? "未知") . "\n";
        exit(1);
    }

    $resultid = $submitResult["resultid"];
    echo "[成功] 任务提交成功!resultid=" . $resultid . "\n";



    // ========== 步骤2:轮询查询识别结果 ==========
    echo "\n" . str_repeat("=", 50) . "\n";
    echo "[查询结果] 正在轮询识别结果...\n";
    echo "[查询结果] 轮询间隔:" . $POLL_INTERVAL . "秒,最大等待:" . $MAX_POLL_TIME . "秒\n";
    echo str_repeat("=", 50) . "\n";

    $startTime = time();
    while (true) {
        $elapsed = time() - $startTime;
        if ($elapsed > $MAX_POLL_TIME) {
            echo "[超时] 已等待" . $MAX_POLL_TIME . "秒,识别超时,请稍后重试\n";
            break;
        }
        sleep($POLL_INTERVAL);
        $queryResult = httpPost($API_BASE . "/results", [
            "appkey" => $APPKEY,
            "resultid" => $resultid
        ]);
        $elapsed = time() - $startTime;
        if (isset($queryResult["status"]) && $queryResult["status"] == 1) {
            echo "\n[成功] 识别成功!耗时:" . ($queryResult["time"] ?? "未知") . "ms\n";
            echo "[识别结果] " . json_encode($queryResult["data"] ?? [], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n";
            echo "\n[完整响应] " . json_encode($queryResult, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n";
            break;
        } else {
            echo "[等待中] 第" . $elapsed . "秒 - " . ($queryResult["msg"] ?? "正在识别中...") . "\n";
        }
    }
} catch (Exception $e) {
    echo "[异常] " . $e->getMessage() . "\n";
}

echo "\n" . str_repeat("=", 50) . "\n";
echo "[完成] 识别执行完毕\n";
echo str_repeat("=", 50) . "\n";
?>

Python

共 2 个示例,按接口动作拆分。

该语言注意事项

跟随当前语言展示
  • =============================================================== 极验识别 对接示例 - Python版 使用说明 =============================================================== 【环境准备】 1. 安装 Python 3.6 或更高版本 下载地址:https://www.python.org/downloads/ 安装时请勾选 "Add Python to PATH" 验证安装:python --version 2. 安装依赖库 打开命令行,执行:pip install requests 如果网络慢可使用国内镜像:pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple 【文件说明】 - query_points.py 查询账户剩余点数(余额) - recognize_geetest.py 极验验证码识别(支持三代/四代,异步轮询) 【参数配置】 1. APPKEY - 用户密钥,登录平台后在个人中心获取 2. GT - 极验gt值(三代为gt值,四代为captcha_id值),从目标网站抓包获取 3. CHALLENGE - 三代必填(每次只能用一次),四代留空 4. ITEM_ID - 项目类型编号,请参照项目价格表选择对应的值 5. REFERER - 验证码所在页面URL,部分网站需要填写 6. PROXY - 代理IP(可选) 7. DEVKEY - 开发者密钥(可选) 【运行方式】 1. 查询点数:python query_points.py 2. 极验识别:python recognize_geetest.py 【极验识别流程说明】 极验识别为异步流程,分两步: 步骤1:提交识别任务 → 返回 resultid 步骤2:使用 resultid 轮询查询结果 → 返回识别数据 脚本已自动实现轮询逻辑,默认每2秒查询一次,最多等待60秒。 【三代与四代的区别】 - 三代:需要传 gt 和 challenge 参数,返回 validate/seccode - 四代:只需传 gt(即captcha_id),无需 challenge,返回 captchaOutput/lotNumber/passToken/genTime 【常见问题】 1. "ModuleNotFoundError: No module named 'requests'" → 执行 pip install requests 2. 提交后返回 "识别类型错误"(status: 4012) → 检查 ITEM_ID 是否与你的极验类型匹配,请参照项目价格表 3. 轮询超时(60秒内无结果) → 可能是网络延迟或服务繁忙,请稍后重试 4. 三代 challenge 无效或已被使用 → challenge 每次只能使用一次,请直接抓包获取新的challenge 【重要注意事项】 - 查询结果接口每秒不得超过1次,否则会被拉黑IP 10分钟 - 查询点数接口每秒不得超过1次,否则会被拉黑24小时 - APPKEY 属于敏感信息,请勿泄露 - 四代如遇无法通过,可能是编码问题,captchaOutput中的'='符号需用%3D替换

查询点数

query_points.py

下载源码
query_points.py

Python

# -*- coding: utf-8 -*-
"""
=============================================================
  查询账户点数 Demo (Python版)

  功能说明:
  查询账户剩余点数(余额)

  使用方法:
  1. 安装依赖:pip install requests
  2. 将下方的 APPKEY 替换为你自己的用户密钥
  3. 运行脚本:python query_points.py
=============================================================
"""

import requests
import json
import sys

# ======================== 配置区域(请替换为你自己的参数)========================
# 用户密钥,登录平台后获取
APPKEY = "你的appkey"
# ===============================================================================

# API基础地址
API_BASE = "http://api.ttocr.com/api"


def query_points():
    """
    查询账户剩余点数
    接口地址:GET http://api.ttocr.com/api/points
    注意:查询点数不得超过1秒1次,否则会被拉黑24小时
    """
    print("=" * 50)
    print("[查询点数] 正在查询账户剩余点数...")
    print("=" * 50)
    url = f"{API_BASE}/points"
    params = {"appkey": APPKEY}
    try:
        response = requests.get(url, params=params, timeout=10)
        result = response.json()
        if result.get("status") == 1:
            print(f"[成功] 查询成功!当前可用点数:{result.get('points')}")
        else:
            print(f"[失败] 查询失败,错误信息:{result.get('msg')}")
            print(f"[提示] 错误状态码:{result.get('status')},请参考错误代码表排查")
        print(f"[完整响应] {json.dumps(result, ensure_ascii=False, indent=2)}")
        return result
    except requests.exceptions.RequestException as e:
        print(f"[异常] 网络请求出错:{e}")
        return None


if __name__ == "__main__":
    print("*" * 60)
    print("  查询账户点数 Demo (Python版)")
    print("*" * 60)
    if APPKEY == "你的appkey":
        print("\n[错误] 请先在脚本顶部的配置区域填写你的 APPKEY")
        sys.exit(1)
    query_points()
    print("\n" + "=" * 50)
    print("[完成] 查询执行完毕")
    print("=" * 50)

提交识别

recognize_geetest.py

下载源码
recognize_geetest.py

Python

# -*- coding: utf-8 -*-
"""
=============================================================
  极验识别 Demo (Python版)

  功能说明:
  提交极验验证码识别任务(支持三代/四代)
  极验识别为异步流程:先提交任务获取resultid,再轮询查询结果

  使用方法:
  1. 安装依赖:pip install requests
  2. 将下方的配置参数替换为你自己的值
  3. 运行脚本:python recognize_geetest.py
=============================================================
"""

import requests
import json
import sys
import time

# ======================== 配置区域(请替换为你自己的参数)========================
# 用户密钥,登录平台后获取
APPKEY = "你的appkey"

# 极验gt值(三代为gt值,四代为captcha_id值)
GT = "你获取到的gt值"

# challenge值(三代必填,每次只能使用一次;四代无需传此参数,留空即可)
CHALLENGE = ""

# 项目类型(请参照项目价格表,不同类型对应不同的itemid)
ITEM_ID = 0

# 验证码所在的页面URL(可选,部分网站需要填写)
REFERER = ""

# 可选参数:代理IP(格式示例:http://IP:端口,若需白名单支持请联系客服。http://账号:密码@proxy.com:8080 或 socks5://127.0.0.1:9888)
PROXY = ""

# 可选参数:开发者密钥(如果有的话填写)
DEVKEY = ""

# 可选参数:SDK版本(特殊版本为2,默认为1)
SDK = ""

# 可选参数:对接模式(按次计费:0,包月计费:1,默认为0。包月用户必填)
GIVEN = ""

# 可选参数:特殊网站极验域名(如api-na.geetest.com,不要带http://和/,只需域名)
HOST = ""

# 可选参数:User-Agent(适用于某些检验UA的网站,只支持传入安卓ua)
USER_AGENT = ""
# ===============================================================================

# API基础地址
API_BASE = "http://api.ttocr.com/api"

# 轮询配置
POLL_INTERVAL = 2    # 轮询间隔(秒),不得低于1秒
MAX_POLL_TIME = 60   # 最大等待时间(秒)


def submit_task():
    """
    步骤1:提交极验识别任务
    接口地址:POST http://api.ttocr.com/api/recognize
    返回resultid用于后续查询结果
    """
    print("=" * 50)
    print("[提交任务] 正在提交极验识别任务...")
    print("=" * 50)
    url = f"{API_BASE}/recognize"
    post_data = {
        "appkey": APPKEY,
        "gt": GT,
        "itemid": ITEM_ID,
    }
    # 三代需要传challenge,四代不需要
    if CHALLENGE:
        post_data["challenge"] = CHALLENGE
    # 验证码所在页面URL,部分网站需要填写
    if REFERER:
        post_data["referer"] = REFERER
    if PROXY:
        post_data["proxy"] = PROXY
    if DEVKEY:
        post_data["devkey"] = DEVKEY
    if SDK:
        post_data["sdk"] = SDK
    if GIVEN:
        post_data["given"] = GIVEN
    if HOST:
        post_data["host"] = HOST
    if USER_AGENT:
        post_data["userAgent"] = USER_AGENT

    print(f"[请求参数] gt={GT[:20]}..." if len(GT) > 20 else f"[请求参数] gt={GT}")
    print(f"[请求参数] itemid={ITEM_ID}")
    print(f"[请求参数] referer={REFERER}")

    try:
        response = requests.post(url, data=post_data, timeout=30)
        result = response.json()
        print(f"[提交响应] {json.dumps(result, ensure_ascii=False, indent=2)}")
        if result.get("status") == 1:
            resultid = result.get("resultid")
            print(f"[成功] 任务提交成功!resultid={resultid}")
            return resultid
        else:
            print(f"[失败] 任务提交失败,错误信息:{result.get('msg')}")
            return None
    except requests.exceptions.RequestException as e:
        print(f"[异常] 网络请求出错:{e}")
        return None


def query_result(resultid):
    """
    步骤2:轮询查询识别结果
    接口地址:POST http://api.ttocr.com/api/results
    注意:查询间隔不低于1秒,否则会被拉黑IP 10分钟
    """
    print("\n" + "=" * 50)
    print("[查询结果] 正在轮询识别结果...")
    print(f"[查询结果] 轮询间隔:{POLL_INTERVAL}秒,最大等待:{MAX_POLL_TIME}秒")
    print("=" * 50)
    url = f"{API_BASE}/results"
    start_time = time.time()
    while True:
        elapsed = time.time() - start_time
        if elapsed > MAX_POLL_TIME:
            print(f"[超时] 已等待{MAX_POLL_TIME}秒,识别超时,请稍后重试")
            return None
        try:
            post_data = {"appkey": APPKEY, "resultid": resultid}
            response = requests.post(url, data=post_data, timeout=30)
            result = response.json()
            if result.get("status") == 1:
                print(f"\n[成功] 识别成功!耗时:{result.get('time')}ms")
                print(f"[识别结果] {json.dumps(result.get('data'), ensure_ascii=False, indent=2)}")
                print(f"\n[完整响应] {json.dumps(result, ensure_ascii=False, indent=2)}")
                return result
            else:
                msg = result.get("msg", "")
                print(f"[等待中] 第{int(elapsed)}秒 - {msg}")
        except requests.exceptions.RequestException as e:
            print(f"[异常] 查询请求出错:{e}")
        time.sleep(POLL_INTERVAL)


if __name__ == "__main__":
    print("*" * 60)
    print("  极验识别 Demo (Python版)")
    print("*" * 60)
    if APPKEY == "你的appkey":
        print("\n[错误] 请先在脚本顶部的配置区域填写你的 APPKEY")
        sys.exit(1)
    if GT == "你获取到的gt值":
        print("\n[错误] 请先在脚本顶部的配置区域填写 GT 值")
        sys.exit(1)
    if ITEM_ID == 0:
        print("\n[错误] 请先在脚本顶部的配置区域填写 ITEM_ID(项目类型)")
        sys.exit(1)

    # 步骤1:提交任务
    resultid = submit_task()
    if resultid:
        # 步骤2:轮询查询结果
        query_result(resultid)
    print("\n" + "=" * 50)
    print("[完成] 识别执行完毕")
    print("=" * 50)

Node.js

共 2 个示例,按接口动作拆分。

该语言注意事项

跟随当前语言展示
  • =============================================================== 极验识别 对接示例 - Node.js版 使用说明 =============================================================== 【环境准备】 1. 安装 Node.js v12 或更高版本 下载地址:https://nodejs.org/ 建议选择 LTS(长期支持)版本 验证安装:node --version 2. 本Demo使用Node.js内置模块(http、querystring),无需安装第三方依赖 【文件说明】 - query_points.js 查询账户剩余点数(余额) - recognize_geetest.js 极验验证码识别(支持三代/四代,异步轮询) 【参数配置】 1. APPKEY - 用户密钥,登录平台后在个人中心获取 2. GT - 极验gt值(三代为gt值,四代为captcha_id值),从目标网站抓包获取 3. CHALLENGE - 三代必填(每次只能用一次),四代留空 4. ITEM_ID - 项目类型编号,请参照项目价格表选择对应的值 5. REFERER - 验证码所在页面URL,部分网站需要填写 6. PROXY - 代理IP(可选) 7. DEVKEY - 开发者密钥(可选) 【运行方式】 1. 查询点数:node query_points.js 2. 极验识别:node recognize_geetest.js 【极验识别流程说明】 极验识别为异步流程,分两步: 步骤1:提交识别任务 → 返回 resultid 步骤2:使用 resultid 轮询查询结果 → 返回识别数据 脚本已自动实现轮询逻辑(async/await),默认每2秒查询一次,最多等待60秒。 【三代与四代的区别】 - 三代:需要传 gt 和 challenge 参数,返回 validate/seccode - 四代:只需传 gt(即captcha_id),无需 challenge,返回 captchaOutput/lotNumber/passToken/genTime 【常见问题】 1. "'node' 不是内部或外部命令" → Node.js未安装或未添加到系统PATH 2. 提交后返回 "识别类型错误" → 检查 ITEM_ID 是否与你的极验类型匹配 3. 轮询超时 → 可能是网络延迟或服务繁忙,请稍后重试 4. 三代 challenge 无效 → challenge 每次只能使用一次,请直接抓包获取 【重要注意事项】 - 查询结果接口每秒不得超过1次,否则会被拉黑IP 10分钟 - 查询点数接口每秒不得超过1次,否则会被拉黑24小时 - APPKEY 属于敏感信息,请勿泄露 - 四代如遇无法通过,captchaOutput中的'='符号需用%3D替换

查询点数

query_points.js

下载源码
query_points.js

Node.js

/**
 * =============================================================
 *   查询账户点数 Demo (Node.js版)
 *
 *   功能说明:
 *   查询账户剩余点数(余额)
 *
 *   使用方法:
 *   1. 确保已安装 Node.js (建议 v12+)
 *   2. 将下方的 APPKEY 替换为你自己的用户密钥
 *   3. 运行脚本:node query_points.js
 *   注意:本Demo使用Node.js内置模块,无需安装第三方依赖
 * =============================================================
 */

const http = require('http');

// ======================== 配置区域(请替换为你自己的参数)========================
// 用户密钥,登录平台后获取
const APPKEY = "你的appkey";
// ===============================================================================

// API基础地址
const API_BASE = "http://api.ttocr.com/api";

/**
 * 发送HTTP GET请求
 */
function httpGet(url) {
    return new Promise((resolve, reject) => {
        http.get(url, { timeout: 10000 }, (res) => {
            let body = '';
            res.on('data', (chunk) => { body += chunk; });
            res.on('end', () => {
                try { resolve(JSON.parse(body)); }
                catch (e) { reject(new Error('JSON解析失败: ' + body)); }
            });
        }).on('error', reject);
    });
}

async function main() {
    console.log("*".repeat(60));
    console.log("  查询账户点数 Demo (Node.js版)");
    console.log("*".repeat(60));

    if (APPKEY === "你的appkey") {
        console.log("\n[错误] 请先在脚本顶部的配置区域填写你的 APPKEY");
        process.exit(1);
    }

    console.log("=".repeat(50));
    console.log("[查询点数] 正在查询账户剩余点数...");
    console.log("=".repeat(50));
    try {
        const url = `${API_BASE}/points?appkey=${encodeURIComponent(APPKEY)}`;
        const result = await httpGet(url);
        if (result.status === 1) {
            console.log(`[成功] 查询成功!当前可用点数:${result.points}`);
        } else {
            console.log(`[失败] 查询失败,错误信息:${result.msg}`);
            console.log(`[提示] 错误状态码:${result.status},请参考错误代码表排查`);
        }
        console.log(`[完整响应] ${JSON.stringify(result, null, 2)}`);
    } catch (e) {
        console.log(`[异常] 网络请求出错:${e.message}`);
    }

    console.log("\n" + "=".repeat(50));
    console.log("[完成] 查询执行完毕");
    console.log("=".repeat(50));
}

main().catch(err => {
    console.error("[致命错误]", err.message);
    process.exit(1);
});

提交识别

recognize_geetest.js

下载源码
recognize_geetest.js

Node.js

/**
 * =============================================================
 *   极验识别 Demo (Node.js版)
 *
 *   功能说明:
 *   提交极验验证码识别任务(支持三代/四代)
 *   极验识别为异步流程:先提交任务获取resultid,再轮询查询结果
 *
 *   使用方法:
 *   1. 确保已安装 Node.js (建议 v12+)
 *   2. 将下方的配置参数替换为你自己的值
 *   3. 运行脚本:node recognize_geetest.js
 *   注意:本Demo使用Node.js内置模块,无需安装第三方依赖
 * =============================================================
 */

const http = require('http');
const querystring = require('querystring');

// ======================== 配置区域(请替换为你自己的参数)========================
// 用户密钥,登录平台后获取
const APPKEY = "你的appkey";

// 极验gt值(三代为gt值,四代为captcha_id值)
const GT = "你获取到的gt值";

// challenge值(三代必填,每次只能使用一次;四代无需传此参数,留空即可)
const CHALLENGE = "";

// 项目类型(请参照项目价格表,不同类型对应不同的itemid)
const ITEM_ID = 0;

// 验证码所在的页面URL(可选,部分网站需要填写)
const REFERER = "";

// 可选参数:代理IP(格式示例:http://IP:端口,若需白名单支持请联系客服。http://账号:密码@proxy.com:8080 或 socks5://127.0.0.1:9888)
const PROXY = "";

// 可选参数:开发者密钥(如果有的话填写)
const DEVKEY = "";

// 可选参数:SDK版本(特殊版本为2,默认为1)
const SDK = "";

// 可选参数:对接模式(按次计费:0,包月计费:1,默认为0。包月用户必填)
const GIVEN = "";

// 可选参数:特殊网站极验域名(如api-na.geetest.com,不要带http://和/,只需域名)
const HOST_PARAM = "";

// 可选参数:User-Agent(适用于某些检验UA的网站,只支持传入安卓ua)
const USER_AGENT = "";
// ===============================================================================

// API基础地址
const API_BASE = "http://api.ttocr.com/api";

// 轮询配置
const POLL_INTERVAL = 2000;  // 轮询间隔(毫秒),不得低于1秒
const MAX_POLL_TIME = 60000; // 最大等待时间(毫秒)

/**
 * 发送HTTP POST请求(表单数据)
 */
function httpPost(url, postData) {
    return new Promise((resolve, reject) => {
        const data = querystring.stringify(postData);
        const urlObj = new URL(url);
        const options = {
            hostname: urlObj.hostname,
            port: urlObj.port || 80,
            path: urlObj.pathname,
            method: 'POST',
            timeout: 30000,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Content-Length': Buffer.byteLength(data)
            }
        };
        const req = http.request(options, (res) => {
            let body = '';
            res.on('data', (chunk) => { body += chunk; });
            res.on('end', () => {
                try { resolve(JSON.parse(body)); }
                catch (e) { reject(new Error('JSON解析失败: ' + body)); }
            });
        });
        req.on('error', reject);
        req.write(data);
        req.end();
    });
}

/**
 * 延时函数
 */
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function main() {
    console.log("*".repeat(60));
    console.log("  极验识别 Demo (Node.js版)");
    console.log("*".repeat(60));

    if (APPKEY === "你的appkey") {
        console.log("\n[错误] 请先在脚本顶部的配置区域填写你的 APPKEY");
        process.exit(1);
    }
    if (GT === "你获取到的gt值") {
        console.log("\n[错误] 请先在脚本顶部的配置区域填写 GT 值");
        process.exit(1);
    }
    if (ITEM_ID === 0) {
        console.log("\n[错误] 请先在脚本顶部的配置区域填写 ITEM_ID(项目类型)");
        process.exit(1);
    }

    // ========== 步骤1:提交极验识别任务 ==========
    console.log("=".repeat(50));
    console.log("[提交任务] 正在提交极验识别任务...");
    console.log("=".repeat(50));

    const postData = { appkey: APPKEY, gt: GT, itemid: ITEM_ID };
    if (CHALLENGE) { postData.challenge = CHALLENGE; }
    if (REFERER) { postData.referer = REFERER; }
    if (PROXY) { postData.proxy = PROXY; }
    if (DEVKEY) { postData.devkey = DEVKEY; }
    if (SDK) { postData.sdk = SDK; }
    if (GIVEN) { postData.given = GIVEN; }
    if (HOST_PARAM) { postData.host = HOST_PARAM; }
    if (USER_AGENT) { postData.userAgent = USER_AGENT; }

    console.log(`[请求参数] gt=${GT}`);
    console.log(`[请求参数] itemid=${ITEM_ID}`);

    try {
        const submitResult = await httpPost(`${API_BASE}/recognize`, postData);
        console.log(`[提交响应] ${JSON.stringify(submitResult, null, 2)}`);

        if (submitResult.status !== 1 || !submitResult.resultid) {
            console.log(`[失败] 任务提交失败,错误信息:${submitResult.msg}`);
            process.exit(1);
        }

        const resultid = submitResult.resultid;
        console.log(`[成功] 任务提交成功!resultid=${resultid}`);


        // ========== 步骤2:轮询查询识别结果 ==========
        console.log("\n" + "=".repeat(50));
        console.log("[查询结果] 正在轮询识别结果...");
        console.log(`[查询结果] 轮询间隔:${POLL_INTERVAL / 1000}秒,最大等待:${MAX_POLL_TIME / 1000}秒`);
        console.log("=".repeat(50));

        const startTime = Date.now();
        while (true) {
            const elapsed = Date.now() - startTime;
            if (elapsed > MAX_POLL_TIME) {
                console.log(`[超时] 已等待${MAX_POLL_TIME / 1000}秒,识别超时,请稍后重试`);
                break;
            }
            await sleep(POLL_INTERVAL);
            const queryResult = await httpPost(`${API_BASE}/results`, {
                appkey: APPKEY,
                resultid: resultid
            });
            const elapsedSec = Math.floor((Date.now() - startTime) / 1000);
            if (queryResult.status === 1) {
                console.log(`\n[成功] 识别成功!耗时:${queryResult.time}ms`);
                console.log(`[识别结果] ${JSON.stringify(queryResult.data, null, 2)}`);
                console.log(`\n[完整响应] ${JSON.stringify(queryResult, null, 2)}`);
                break;
            } else {
                console.log(`[等待中] 第${elapsedSec}秒 - ${queryResult.msg || '正在识别中...'}`);
            }
        }
    } catch (e) {
        console.log(`[异常] 网络请求出错:${e.message}`);
    }

    console.log("\n" + "=".repeat(50));
    console.log("[完成] 识别执行完毕");
    console.log("=".repeat(50));
}

main().catch(err => {
    console.error("[致命错误]", err.message);
    process.exit(1);
});

Java

共 2 个示例,按接口动作拆分。

该语言注意事项

跟随当前语言展示
  • =============================================================== 极验识别 对接示例 - Java版 使用说明 =============================================================== 【环境准备】 1. 安装 JDK 8 或更高版本 下载地址:https://www.oracle.com/java/technologies/downloads/ 或使用 OpenJDK:https://adoptium.net/ 验证安装:java -version 和 javac -version 【文件说明】 - QueryPoints.java 查询账户剩余点数(余额) - RecognizeGeetest.java 极验验证码识别(支持三代/四代,异步轮询) 【参数配置】 1. APPKEY - 用户密钥,登录平台后在个人中心获取 2. GT - 极验gt值(三代为gt值,四代为captcha_id值),从目标网站抓包获取 3. CHALLENGE - 三代必填(每次只能用一次),四代留空 4. ITEM_ID - 项目类型编号,请参照项目价格表选择对应的值 5. REFERER - 验证码所在页面URL,部分网站需要填写 6. PROXY - 代理IP(可选) 7. DEVKEY - 开发者密钥(可选) 【编译与运行】 1. 查询点数: javac -encoding UTF-8 QueryPoints.java java QueryPoints 2. 极验识别: javac -encoding UTF-8 RecognizeGeetest.java java RecognizeGeetest 注意:编译时必须加 -encoding UTF-8 参数,否则中文可能乱码。 【极验识别流程说明】 极验识别为异步流程,分两步: 步骤1:提交识别任务 → 返回 resultid 步骤2:使用 resultid 轮询查询结果 → 返回识别数据 脚本已自动实现轮询逻辑,默认每2秒查询一次,最多等待60秒。 本Demo使用纯JDK实现,无需任何第三方依赖库。 【三代与四代的区别】 - 三代:需要传 gt 和 challenge 参数,返回 validate/seccode - 四代:只需传 gt(即captcha_id),无需 challenge,返回 captchaOutput/lotNumber/passToken/genTime 【常见问题】 1. "javac 不是内部或外部命令" → JDK未安装或未配置环境变量,请将JDK的bin目录添加到PATH 2. 编译时出现中文乱码 → 编译命令加上 -encoding UTF-8 参数 3. 提交后返回 "识别类型错误" → 检查 ITEM_ID 是否与你的极验类型匹配 4. 三代 challenge 无效 → challenge 每次只能使用一次,请直接抓包获取 【重要注意事项】 - 查询结果接口每秒不得超过1次,否则会被拉黑IP 10分钟 - 查询点数接口每秒不得超过1次,否则会被拉黑24小时 - APPKEY 属于敏感信息,请勿泄露 - 四代如遇无法通过,captchaOutput中的'='符号需用%3D替换

查询点数

QueryPoints.java

下载源码
QueryPoints.java

Java

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;

/**
 * =============================================================
 *   查询账户点数 Demo (Java版)
 *
 *   功能说明:
 *   查询账户剩余点数(余额)
 *
 *   使用方法:
 *   1. 将下方的 APPKEY 替换为你自己的用户密钥
 *   2. 编译运行:javac -encoding UTF-8 QueryPoints.java && java QueryPoints
 * =============================================================
 */
public class QueryPoints {

    // ======================== 配置区域(请替换为你自己的参数)========================
    // 用户密钥,登录平台后获取
    private static final String APPKEY = "你的appkey";
    // ===============================================================================

    // API基础地址
    private static final String API_BASE = "http://api.ttocr.com/api";

    /**
     * 发送GET请求
     */
    private static String httpGet(String urlStr) throws Exception {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setConnectTimeout(10000);
        conn.setReadTimeout(10000);
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        reader.close();
        conn.disconnect();
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.println("************************************************************");
        System.out.println("  查询账户点数 Demo (Java版)");
        System.out.println("************************************************************");

        if ("你的appkey".equals(APPKEY)) {
            System.out.println("\n[错误] 请先在代码顶部的配置区域填写你的 APPKEY");
            System.exit(1);
        }

        System.out.println("==================================================");
        System.out.println("[查询点数] 正在查询账户剩余点数...");
        System.out.println("==================================================");
        try {
            String url = API_BASE + "/points?appkey=" + URLEncoder.encode(APPKEY, "UTF-8");
            String result = httpGet(url);
            System.out.println("[完整响应] " + result);
        } catch (Exception e) {
            System.out.println("[异常] 网络请求出错:" + e.getMessage());
        }

        System.out.println("\n==================================================");
        System.out.println("[完成] 查询执行完毕");
        System.out.println("==================================================");
    }
}

提交识别

RecognizeGeetest.java

下载源码
RecognizeGeetest.java

Java

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;

/**
 * =============================================================
 *   极验识别 Demo (Java版)
 *
 *   功能说明:
 *   提交极验验证码识别任务(支持三代/四代)
 *   极验识别为异步流程:先提交任务获取resultid,再轮询查询结果
 *
 *   使用方法:
 *   1. 将下方的配置参数替换为你自己的值
 *   2. 编译运行:javac -encoding UTF-8 RecognizeGeetest.java && java RecognizeGeetest
 * =============================================================
 */
public class RecognizeGeetest {

    // ======================== 配置区域(请替换为你自己的参数)========================
    // 用户密钥,登录平台后获取
    private static final String APPKEY = "你的appkey";

    // 极验gt值(三代为gt值,四代为captcha_id值)
    private static final String GT = "你获取到的gt值";

    // challenge值(三代必填,每次只能使用一次;四代无需传此参数,留空即可)
    private static final String CHALLENGE = "";

    // 项目类型(请参照项目价格表,不同类型对应不同的itemid)
    private static final int ITEM_ID = 0;

    // 验证码所在的页面URL(可选,部分网站需要填写)
    private static final String REFERER = "";

    // 可选参数:代理IP(格式示例:http://IP:端口,若需白名单支持请联系客服。http://账号:密码@proxy.com:8080 或 socks5://127.0.0.1:9888)
    private static final String PROXY = "";

    // 可选参数:开发者密钥(如果有的话填写)
    private static final String DEVKEY = "";

    // 可选参数:SDK版本(特殊版本为2,默认为1)
    private static final String SDK = "";

    // 可选参数:对接模式(按次计费:0,包月计费:1,默认为0。包月用户必填)
    private static final String GIVEN = "";

    // 可选参数:特殊网站极验域名(如api-na.geetest.com,不要带http://和/,只需域名)
    private static final String HOST_PARAM = "";

    // 可选参数:User-Agent(适用于某些检验UA的网站,只支持传入安卓ua)
    private static final String USER_AGENT = "";
    // ===============================================================================

    // API基础地址
    private static final String API_BASE = "http://api.ttocr.com/api";

    // 轮询配置
    private static final int POLL_INTERVAL = 2000;  // 轮询间隔(毫秒),不得低于1秒
    private static final int MAX_POLL_TIME = 60000; // 最大等待时间(毫秒)

    /**
     * 发送POST请求(表单数据)
     */
    private static String httpPost(String urlStr, String postData) throws Exception {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setConnectTimeout(10000);
        conn.setReadTimeout(30000);
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        OutputStream os = conn.getOutputStream();
        os.write(postData.getBytes(StandardCharsets.UTF_8));
        os.flush();
        os.close();
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        reader.close();
        conn.disconnect();
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.println("************************************************************");
        System.out.println("  极验识别 Demo (Java版)");
        System.out.println("************************************************************");

        if ("你的appkey".equals(APPKEY)) {
            System.out.println("\n[错误] 请先在代码顶部的配置区域填写你的 APPKEY");
            System.exit(1);
        }
        if ("你获取到的gt值".equals(GT)) {
            System.out.println("\n[错误] 请先在代码顶部的配置区域填写 GT 值");
            System.exit(1);
        }
        if (ITEM_ID == 0) {
            System.out.println("\n[错误] 请先在代码顶部的配置区域填写 ITEM_ID(项目类型)");
            System.exit(1);
        }

        try {
            // ========== 步骤1:提交极验识别任务 ==========
            System.out.println("==================================================");
            System.out.println("[提交任务] 正在提交极验识别任务...");
            System.out.println("==================================================");

            StringBuilder postData = new StringBuilder();
            postData.append("appkey=").append(URLEncoder.encode(APPKEY, "UTF-8"));
            postData.append("&gt=").append(URLEncoder.encode(GT, "UTF-8"));
            postData.append("&itemid=").append(ITEM_ID);
            if (CHALLENGE != null && !CHALLENGE.isEmpty()) {
                postData.append("&challenge=").append(URLEncoder.encode(CHALLENGE, "UTF-8"));
            }
            if (REFERER != null && !REFERER.isEmpty()) {
                postData.append("&referer=").append(URLEncoder.encode(REFERER, "UTF-8"));
            }
            if (PROXY != null && !PROXY.isEmpty()) {
                postData.append("&proxy=").append(URLEncoder.encode(PROXY, "UTF-8"));
            }
            if (DEVKEY != null && !DEVKEY.isEmpty()) {
                postData.append("&devkey=").append(URLEncoder.encode(DEVKEY, "UTF-8"));
            }
            if (SDK != null && !SDK.isEmpty()) {
                postData.append("&sdk=").append(URLEncoder.encode(SDK, "UTF-8"));
            }
            if (GIVEN != null && !GIVEN.isEmpty()) {
                postData.append("&given=").append(URLEncoder.encode(GIVEN, "UTF-8"));
            }
            if (HOST_PARAM != null && !HOST_PARAM.isEmpty()) {
                postData.append("&host=").append(URLEncoder.encode(HOST_PARAM, "UTF-8"));
            }
            if (USER_AGENT != null && !USER_AGENT.isEmpty()) {
                postData.append("&userAgent=").append(URLEncoder.encode(USER_AGENT, "UTF-8"));
            }

            System.out.println("[请求参数] gt=" + GT);
            System.out.println("[请求参数] itemid=" + ITEM_ID);

            String submitUrl = API_BASE + "/recognize";
            String submitResult = httpPost(submitUrl, postData.toString());
            System.out.println("[提交响应] " + submitResult);


            // 简单解析resultid(无需JSON库)
            String resultid = null;
            if (submitResult.contains("\"status\":") && submitResult.contains("\"resultid\":")) {
                // 提取status值
                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);
                        System.out.println("[成功] 任务提交成功!resultid=" + resultid);
                    }
                } else {
                    System.out.println("[失败] 任务提交失败");
                }
            }

            if (resultid == null || resultid.isEmpty()) {
                System.out.println("[失败] 未获取到resultid,请检查参数配置");
                System.exit(1);
            }

            // ========== 步骤2:轮询查询识别结果 ==========
            System.out.println("\n==================================================");
            System.out.println("[查询结果] 正在轮询识别结果...");
            System.out.println("[查询结果] 轮询间隔:" + (POLL_INTERVAL / 1000) + "秒,最大等待:" + (MAX_POLL_TIME / 1000) + "秒");
            System.out.println("==================================================");

            String queryUrl = API_BASE + "/results";
            long startTime = System.currentTimeMillis();
            while (true) {
                long elapsed = System.currentTimeMillis() - startTime;
                if (elapsed > MAX_POLL_TIME) {
                    System.out.println("[超时] 已等待" + (MAX_POLL_TIME / 1000) + "秒,识别超时,请稍后重试");
                    break;
                }
                Thread.sleep(POLL_INTERVAL);
                String queryData = "appkey=" + URLEncoder.encode(APPKEY, "UTF-8")
                        + "&resultid=" + URLEncoder.encode(resultid, "UTF-8");
                String queryResult = httpPost(queryUrl, queryData);
                elapsed = System.currentTimeMillis() - startTime;
                if (queryResult.contains("\"status\": 1") || queryResult.contains("\"status\":1")) {
                    System.out.println("\n[成功] 识别成功!");
                    System.out.println("[完整响应] " + queryResult);
                    break;
                } else {
                    System.out.println("[等待中] 第" + (elapsed / 1000) + "秒 - 正在识别中...");
                }
            }
        } catch (Exception e) {
            System.out.println("[异常] 网络请求出错:" + e.getMessage());
        }

        System.out.println("\n==================================================");
        System.out.println("[完成] 识别执行完毕");
        System.out.println("==================================================");
    }
}

C#

共 2 个示例,按接口动作拆分。

该语言注意事项

跟随当前语言展示
  • =============================================================== 极验识别 对接示例 - C#版 使用说明 =============================================================== 【环境准备】 1. 安装 .NET Framework 4.5+ 或 .NET Core/.NET 5+ - Windows系统通常自带 .NET Framework 和 csc 编译器 - .NET Core 下载:https://dotnet.microsoft.com/download 验证安装:csc /? 或 dotnet --version 【文件说明】 - QueryPoints.cs 查询账户剩余点数(余额) - RecognizeGeetest.cs 极验验证码识别(支持三代/四代,异步轮询) 【参数配置】 1. APPKEY - 用户密钥,登录平台后在个人中心获取 2. GT - 极验gt值(三代为gt值,四代为captcha_id值),从目标网站抓包获取 3. CHALLENGE - 三代必填(每次只能用一次),四代留空 4. ITEM_ID - 项目类型编号,请参照项目价格表选择对应的值 5. REFERER - 验证码所在页面URL,部分网站需要填写 6. PROXY - 代理IP(可选) 7. DEVKEY - 开发者密钥(可选) 【编译与运行】 方式一:使用 .NET Framework csc 编译器 1. 查询点数: csc /out:QueryPoints.exe QueryPoints.cs QueryPoints.exe 2. 极验识别: csc /out:RecognizeGeetest.exe RecognizeGeetest.cs RecognizeGeetest.exe 注意:csc 通常位于: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe 如果 csc 不在 PATH 中,请使用完整路径。 方式二:使用 .NET Core / .NET 5+ 1. 创建项目:dotnet new console -n GeetestDemo 2. 将对应的 .cs 文件内容替换 Program.cs 3. 运行:dotnet run 【极验识别流程说明】 极验识别为异步流程,分两步: 步骤1:提交识别任务 → 返回 resultid 步骤2:使用 resultid 轮询查询结果 → 返回识别数据 脚本已自动实现轮询逻辑(Thread.Sleep),默认每2秒查询一次,最多等待60秒。 本Demo使用 System.Net 内置类,无需任何NuGet包。 【三代与四代的区别】 - 三代:需要传 gt 和 challenge 参数,返回 validate/seccode - 四代:只需传 gt(即captcha_id),无需 challenge,返回 captchaOutput/lotNumber/passToken/genTime 【常见问题】 1. "'csc' 不是内部或外部命令" → 使用完整路径:C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe 2. 编译报错中文乱码 → 确保源文件保存为 UTF-8 编码 3. 提交后返回 "识别类型错误" → 检查 ITEM_ID 是否与你的极验类型匹配 4. 三代 challenge 无效 → challenge 每次只能使用一次,请直接抓包获取 【重要注意事项】 - 查询结果接口每秒不得超过1次,否则会被拉黑IP 10分钟 - 查询点数接口每秒不得超过1次,否则会被拉黑24小时 - APPKEY 属于敏感信息,请勿泄露 - 四代如遇无法通过,captchaOutput中的'='符号需用%3D替换

查询点数

QueryPoints.cs

下载源码
QueryPoints.cs

C#

using System;
using System.IO;
using System.Net;
using System.Text;

/// <summary>
/// =============================================================
///   查询账户点数 Demo (C#版)
///
///   功能说明:
///   查询账户剩余点数(余额)
///
///   使用方法:
///   1. 将下方的 APPKEY 替换为你自己的用户密钥
///   2. 编译运行:csc /out:QueryPoints.exe QueryPoints.cs && QueryPoints.exe
/// =============================================================
/// </summary>
class QueryPoints
{
    // ======================== 配置区域(请替换为你自己的参数)========================
    // 用户密钥,登录平台后获取
    static string APPKEY = "你的appkey";
    // ===============================================================================

    // API基础地址
    static string API_BASE = "http://api.ttocr.com/api";

    /// <summary>
    /// 发送GET请求
    /// </summary>
    static string HttpGet(string url)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "GET";
        request.Timeout = 10000;
        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);
        }

        Console.WriteLine(new string('=', 50));
        Console.WriteLine("[查询点数] 正在查询账户剩余点数...");
        Console.WriteLine(new string('=', 50));
        try
        {
            string url = API_BASE + "/points?appkey=" + Uri.EscapeDataString(APPKEY);
            string result = HttpGet(url);
            Console.WriteLine("[完整响应] " + result);
        }
        catch (Exception e)
        {
            Console.WriteLine("[异常] 网络请求出错:" + e.Message);
        }

        Console.WriteLine("\n" + new string('=', 50));
        Console.WriteLine("[完成] 查询执行完毕");
        Console.WriteLine(new string('=', 50));
    }
}

提交识别

RecognizeGeetest.cs

下载源码
RecognizeGeetest.cs

C#

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;

/// <summary>
/// =============================================================
///   极验识别 Demo (C#版)
///
///   功能说明:
///   提交极验验证码识别任务(支持三代/四代)
///   极验识别为异步流程:先提交任务获取resultid,再轮询查询结果
///
///   使用方法:
///   1. 将下方的配置参数替换为你自己的值
///   2. 编译运行:csc /out:RecognizeGeetest.exe RecognizeGeetest.cs && RecognizeGeetest.exe
/// =============================================================
/// </summary>
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; // 最大等待时间(毫秒)

    /// <summary>
    /// 发送POST请求(表单数据)
    /// </summary>
    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("&gt=").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));
    }
}