如何识别极验(GeeTest)v3
上方的方框是一个实时的 极验 v3 挑战,即滑动拼合拼图。本页面展示三种简单方式来识别极验 v3 并获取它返回的三个值, geetest_challenge, geetest_validate 和 geetest_seccode:使用 CapSkip 浏览器扩展自动识别、用 CapSkip SDK 在你自己的代码中识别,或将你的工具已经调用的验证码服务重新路由到 CapSkip。CapSkip 在你的设备上本地运行,因此没有按次付费,也没有任何数据离开你的机器。
方式一:使用浏览器扩展识别极验 v3
绕过极验 v3 最简单的方式是 CapSkip 验证码识别扩展 适用于 Chrome 和 Firefox。它会找到拼图中的缺口,以类似人类的动作将拼图拖到位,并向站点提供一个有效的 seccode,无需编写代码。
安装扩展
从 Chrome 应用商店或 Firefox 附加组件添加 CapSkip。它同样适用于 Brave、Edge、Opera 和 Vivaldi。
运行 CapSkip 应用
安装并打开 CapSkip 桌面应用。它在你自己的设备上完成识别,并与扩展配对。
它会自动识别
重新加载本页面,CapSkip 就会为你将拼图块滑入缺口。希望自己掌控?随时可切换到手动模式。
方式二:使用 CapSkip SDK 识别极验 v3
在构建自动化、爬虫或机器人?使用 CapSkip 验证码识别 SDK 来识别极验 v3,支持 Python, Node.js, PHP 或 C#。你传入本页面的 gt、一个全新的 challenge 以及页面 URL,CapSkip 就会返回识别出的 challenge、validate 和 seccode 值,你可以像真实值一样提交它们。
e3a600a044ef0ad51749da5c451adca0https://capskip.com/zh/captcha-demo/geetest-v3/开始之前
CapSkip 在本地识别。下载并运行 CapSkip 桌面应用 并让它在后台保持打开。SDK 通过 127.0.0.1:8080与它通信,因此没有云端调用,也没有按次费用。
该 challenge 会过期
与 reCAPTCHA 的 site key 不同,极验 v3 需要两个值。 gt 上面这个是静态的,永远不会改变,而 challenge 是一次性的,大约一分钟后就会失效,并且在小组件加载它的那一刻就被消耗掉。每次识别前立即获取一个全新的值,这正是步骤 2 所做的。
安装 SDK
将官方 CapSkip 客户端添加到你的项目中。
pip install capskipnpm install capskipcomposer require capskip/capskipdotnet add package CapSkip获取全新的 gt 和 challenge
本页面在服务器端注册其极验 challenge,并将所需的 nonce 打印在一个内联的 capskipCaptcha 对象。读取它,然后向页面请求一个属于你自己的挑战,这样小组件正在使用的那个挑战就不会被改动。
import json, re, requests
PAGE = "https://capskip.com/zh/captcha-demo/geetest-v3/"
AJAX = "https://capskip.com/wp-admin/admin-ajax.php"
session = requests.Session()
html = session.get(PAGE).text
# The page prints its ajax nonce and page id in an inline capskipCaptcha object
cfg = json.loads(re.search(r"capskipCaptcha\s*=\s*(\{.*\});", html).group(1))
# Register a fresh challenge (single use, expires in about a minute)
data = session.post(AJAX, data={
"action": "capskip_geetest_register",
"nonce": cfg["nonce"],
"post_id": cfg["postId"],
}).json()["data"]
gt, challenge = data["gt"], data["challenge"]
print(gt, challenge)const PAGE = 'https://capskip.com/zh/captcha-demo/geetest-v3/';
const AJAX = 'https://capskip.com/wp-admin/admin-ajax.php';
const html = await (await fetch(PAGE)).text();
// The page prints its ajax nonce and page id in an inline capskipCaptcha object
const cfg = JSON.parse(html.match(/capskipCaptcha\s*=\s*(\{.*\});/)[1]);
// Register a fresh challenge (single use, expires in about a minute)
const res = await fetch(AJAX, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
action: 'capskip_geetest_register',
nonce: cfg.nonce,
post_id: cfg.postId,
}),
});
const { gt, challenge } = (await res.json()).data;
console.log(gt, challenge);<?php
$page = 'https://capskip.com/zh/captcha-demo/geetest-v3/';
$ajax = 'https://capskip.com/wp-admin/admin-ajax.php';
$html = file_get_contents($page);
// The page prints its ajax nonce and page id in an inline capskipCaptcha object
preg_match('/capskipCaptcha\s*=\s*(\{.*\});/', $html, $m);
$cfg = json_decode($m[1], true);
// Register a fresh challenge (single use, expires in about a minute)
$res = file_get_contents($ajax, false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query([
'action' => 'capskip_geetest_register',
'nonce' => $cfg['nonce'],
'post_id' => $cfg['postId'],
]),
],
]));
$data = json_decode($res, true)['data'];
$gt = $data['gt'];
$challenge = $data['challenge'];
echo $gt, ' ', $challenge;using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
const string Page = "https://capskip.com/zh/captcha-demo/geetest-v3/";
const string Ajax = "https://capskip.com/wp-admin/admin-ajax.php";
var http = new HttpClient();
var html = await http.GetStringAsync(Page);
// The page prints its ajax nonce and page id in an inline capskipCaptcha object
var cfg = JsonNode.Parse(Regex.Match(html, @"capskipCaptcha\s*=\s*(\{.*\});").Groups[1].Value)!;
// Register a fresh challenge (single use, expires in about a minute)
var form = new FormUrlEncodedContent(new Dictionary<string, string> {
["action"] = "capskip_geetest_register",
["nonce"] = cfg["nonce"]!.ToString(),
["post_id"] = cfg["postId"]!.ToString(),
});
var res = await http.PostAsync(Ajax, form);
var data = JsonNode.Parse(await res.Content.ReadAsStringAsync())!["data"]!;
string gt = data["gt"]!.ToString();
string challenge = data["challenge"]!.ToString();
Console.WriteLine($"{gt} {challenge}");你会得到页面的 gt 以及一个全新的 32 字符 challenge。立即识别它。
识别极验 v3 并获取三个值
传入 gt、你刚刚注册的 challenge 以及本页面的 url 设置为 geetest()。CapSkip 会将拼图块拖入缺口并返回识别出的三元组。
from capskip import CapSkip
# Connect to the CapSkip app running on your machine
solver = CapSkip(host="127.0.0.1", port=8080)
# Solve the GeeTest v3 slider on this page
result = solver.geetest(
gt=gt,
challenge=challenge,
url="https://capskip.com/zh/captcha-demo/geetest-v3/",
)
print(result["challenge"]) # geetest_challenge
print(result["validate"]) # geetest_validate
print(result["seccode"]) # geetest_seccodeconst { CapSkip } = require('capskip');
// Connect to the CapSkip app running on your machine
const solver = new CapSkip({ host: '127.0.0.1', port: 8080 });
// Solve the GeeTest v3 slider on this page
const result = await solver.geetest(
gt,
challenge,
'https://capskip.com/zh/captcha-demo/geetest-v3/',
);
console.log(result.challenge); // geetest_challenge
console.log(result.validate); // geetest_validate
console.log(result.seccode); // geetest_seccode<?php
require 'vendor/autoload.php';
use CapSkip\CapSkip;
// Connect to the CapSkip app running on your machine
$solver = new CapSkip(['host' => '127.0.0.1', 'port' => 8080]);
// Solve the GeeTest v3 slider on this page
$result = $solver->geetest(
$gt,
$challenge,
'https://capskip.com/zh/captcha-demo/geetest-v3/'
);
echo $result['challenge']; // geetest_challenge
echo $result['validate']; // geetest_validate
echo $result['seccode']; // geetest_seccodeusing CapSkip;
// Connect to the CapSkip app running on your machine
var solver = new CapSkipClient(host: "127.0.0.1", port: 8080);
// Solve the GeeTest v3 slider on this page
var result = await solver.GeetestAsync(
gt,
challenge,
"https://capskip.com/zh/captcha-demo/geetest-v3/");
Console.WriteLine(result.Challenge); // geetest_challenge
Console.WriteLine(result.Validate); // geetest_validate
Console.WriteLine(result.Seccode); // geetest_seccode你会得到 challenge, validate 和 seccode,可直接提交。
使用这三个值
以小组件自身使用的名称将三元组回传。在本页面上,这与 校验 步骤所发出的 admin-ajax 调用相同,它会先向极验校验 seccode,然后小组件才变为绿色。
// The three values GeeTest returns, exactly as the widget produces them
const payload = {
geetest_challenge: result.challenge,
geetest_validate: result.validate,
geetest_seccode: result.seccode,
};
// Send them to whatever endpoint the site verifies with, then submit the form.
// This demo posts challenge, validate and seccode to admin-ajax.php with
// action=capskip_captcha_verify and provider=geetest_v3.在其他极验 v3 站点上使用 CapSkip
要在任意地方识别极验 v3,你需要从页面获取三样东西:
- gt: 公开的验证码 ID,每个站点固定不变。它是
gt查询参数,见于小组件对以下地址的调用:api.geetest.com/gettype.php和get.php. - challenge: 一次性的值,来自站点自身的 init 或 register 请求,通常是紧邻
gt的一个小型 JSON 响应。每次识别前重放那一个请求,即可获取一个全新的 challenge。 - 页面 URL: 页面的完整地址。
区域 API 服务器和代理
有些站点被固定到某个区域的极验端点,例如 api-na.geetest.com在 HTTP API 上将它作为 api_server 传入。此外也支持一个 proxy (proxy 和 proxytype),这在站点将 challenge 绑定到你的 IP 时很有用。
result = solver.geetest(
gt="GT_FROM_PAGE",
challenge="FRESH_CHALLENGE", # register a new one right before every solve
url="https://example.com/login",
)
challenge = result["challenge"] # geetest_challenge
validate = result["validate"] # geetest_validate
seccode = result["seccode"] # geetest_seccodeconst result = await solver.geetest(
'GT_FROM_PAGE',
'FRESH_CHALLENGE', // register a new one right before every solve
'https://example.com/login',
);
const { challenge, validate, seccode } = result;$result = $solver->geetest(
'GT_FROM_PAGE',
'FRESH_CHALLENGE', // register a new one right before every solve
'https://example.com/login'
);
$challenge = $result['challenge']; // geetest_challenge
$validate = $result['validate']; // geetest_validate
$seccode = $result['seccode']; // geetest_seccodevar result = await solver.GeetestAsync(
"GT_FROM_PAGE",
"FRESH_CHALLENGE", // register a new one right before every solve
"https://example.com/login");
string challenge = result.Challenge; // geetest_challenge
string validate = result.Validate; // geetest_validate
string seccode = result.Seccode; // geetest_seccode如果一次识别返回被拒绝,通常的原因是 过期的 challenge:它已被页面使用过,或闲置超过一分钟。
不使用 Python、Node.js、PHP 或 C#?这些 SDK 只是 CapSkip HTTP API 的封装(即标准的 由以下端点返回的验证码 ID: / res.php 端点,并配合 method=geetest),因此你可以从 任何语言、框架或工具识别 reCAPTCHA v2。参见 极验 v3 API 参考.
选项 3:将你现有的识别服务代码发送到 CapSkip
已经在通过按次付费的验证码服务(例如 2Captcha, Anti-Captcha 或 CapMonster)识别基于回调的 reCAPTCHA v2?你无需重写一行代码。CapSkip 应用包含一个 服务模拟器 ,它在本地讲这些服务自己的 API:选择你使用的服务,点击 添加到 hosts 文件,你的机器人、爬虫或现成工具已经发送给它的每个请求,都会由 CapSkip 在你自己的机器上响应,采用统一价格而非按次账单。
选择你的服务
打开 CapSkip 应用,选择你的代码已经在对接的服务:2Captcha、RuCaptcha、Anti-Captcha、CapMonster Cloud、CapSolver、DeathByCaptcha、SolveCaptcha 或 Captchas.io。
添加到 hosts 文件
在应用中一键将该服务的域名指向 CapSkip,于是你的工具发出的调用会在你自己的机器上得到响应,而不是发往付费 API。
原样运行你的工具
相同的 API key、相同的请求、相同的轮询循环。CapSkip 以该服务自身的格式回复,你的代码会得到识别出的 challenge、validate 和 seccode 值。
切换后,下面的内容不会有任何变化。这与你的代码今天发出的调用完全相同,只不过现在极验 v3 在本地识别,并且识别出的 challenge、validate 和 seccode 值会从 CapSkip 返回:
POST https://2captcha.com/in.php
key=YOUR_EXISTING_API_KEY
method=geetest
gt=e3a600a044ef0ad51749da5c451adca0
challenge=FRESH_CHALLENGE_FROM_THE_PAGE
pageurl=https://capskip.com/zh/captcha-demo/geetest-v3/
GET https://2captcha.com/res.php?key=YOUR_EXISTING_API_KEY&action=get&id=2122988149
{"geetest_challenge":"…","geetest_validate":"…","geetest_seccode":"…"}客户端库同样如此:Anti-Captcha 风格的 createTask / getTaskResult 配对,或任何基于这些服务构建的封装,在模拟器开启后都能继续工作。完整的请求和响应参考见 CapSkip API 文档.
关于识别极验 v3 的更多内容
针对人们通常与此演示搭配使用的工具和语言的指南。
关于本极验 v3 演示
本页是一个实时的 GeeTest v3 演示 在这里你可以测试滑动拼合拼图的工作原理,并实时观看它被识别的过程。极验 v3 是你在全球登录和注册表单上都会遇到的滑块验证码:从一张图片中切出一块,你需要把它拖回缺口中。识别成功后,极验会返回三个值, geetest_challenge, geetest_validate 和 geetest_seccode,你的服务器会用它们向极验校验后才信任该请求。
开发者、测试人员和自动化工程师可以使用这个极验 v3 测试页面,观察 challenge 注册、滑块触发和三元组返回的过程,并对 CapSkip 识别极验 v3 的表现进行基准测试。无论你需要识别一次极验还是自动化数千次识别,CapSkip 都是一款 GeeTest 识别工具 ,它有三种工作方式:面向 Chrome 和 Firefox 的免代码 验证码识别扩展 ,面向 Python、Node.js、PHP 和 C# 的 验证码识别 SDK ,以及对你今天可能按次付费的验证码服务的即插即用模拟,全部以统一价格无限量识别。三者都由同一个桌面 AI 验证码识别工具驱动,安装一次即可在你自己的机器上运行,因此没有任何内容在远程服务器排队,也没有任何按次计费。
