动态验证码参数:它们是什么,如何识别和提取它们。使用动态数据成功解决验证码问题
如今,很难想象现代网络资源中没有某些保护机制,例如验证码,其目的是验证访问者是真正的人类,而不是构成潜在威胁的僵尸。过去,这些验证码主要是基于文本的验证码,用户需要将图像中的字符输入指定字段或回答简单的问题。随着时间的推移,用户验证系统和网站保护机制变得越来越复杂,以应对自动程序。
目前,验证不仅依赖于通过特定的测试,还依赖于分析广泛的因素:用户行为、浏览器特征、网络请求等。网站可以检查 cookie、设备指纹和 JavaScript 的执行情况,只有在检测到可疑活动时才显示验证码。
所谓的动态参数又增加了一层保护。这些参数随每次验证码请求而创建和更新。它们是每个验证会话的唯一标识符,与保持不变的静态参数(如 websitekey)不同,动态参数会随每次验证码请求而改变。
每次用户请求验证码时,服务器都会生成一个新的数据集(例如:challenge、context、token 等)、
这些参数可防止重复使用响应,并可能包括有关用户、会话或时间戳的信息。
通过分析会话和行为数据,网站可以识别僵尸活动并临时阻止可疑设备,甚至无需发出验证码。
这些措施可确保只有真实用户才能通过 "转门",而机器人则会被阻止或在解决保护问题时面临重大障碍。
验证码参数的变化取决于使用的解决方案,一般来说取决于使用的供应商和保护系统。它们在会话期间或完成会话后生成。让我们来看看它们的主要重要类型:
- 挑战实际上就是验证码元素本身,用户必须解决它来确认自己的身份。它可以采取多种形式,包括基于文本的任务、图像选择或执行某些操作。验证码由服务器在页面加载时创建,每次请求都有一个唯一的验证码。
- 令牌用于验证用户会话,并确认请求来自真实用户而非机器人。令牌可在服务器端创建并传输到客户端,以便在验证码流程中使用。令牌通常在会话开始时或每次请求验证码时生成,成功通过验证码后,令牌将被发送回服务器进行验证。
除了挑战和令牌,不同类型的验证码还可以使用特定的其他参数。以下是其中的一些:
- 上下文(例如,在 AWS WAF 中使用)- 包含与当前用户会话绑定的唯一值。在 window.gokuProps 中生成:
window.gokuProps = {
"key":""、
"iv":""、
"context":""
};
- geetest_challenge 或 challenge(用于 GeeTestv.3)是一个验证码标识符,可将用户请求链接到特定验证会话。它在 URL 中生成,看起来像这样(请注意,该链接包含一个时间戳,以防止请求被缓存):
https://example.com/api/v1/gee-test/init-params?t=1730640766594
GeeTest v.3 还使用以下参数:
- geetest_validate - 确认验证码已正确解决的代码。在成功解决验证码后生成,并确认检查已通过;
- geetest_seccode - 确认成功解决验证码的附加安全代码。
- dataDomeCookie (用于 DataDome)- DataDome 系统生成的 cookies,用于跟踪和检查用户的自动操作,并根据用户的行为进行更新。
- g-recaptcha-response (用于 ReCAPTCHA)-
- cf_clearance(用于 Cloudflare检查)- 通过验证码后生成的 cookie,用于成功访问资源。
值得一提的参数还有:
- s(或 sentinel/motionData)- 可包含有关鼠标移动和与验证码交互的数据。
- v(版本)- 指定可在服务器上更新的验证码版本,并要求每次会话都更新值。
- rqdata--包含加密的用户会话数据。
所给出的示例仅反映了随每次会话而变化的部分参数;事实上,这些参数有很多,而且每种类型的检查(验证码)都不尽相同。
查找动态参数,使用开发工具
如果您使用验证码解决服务,例如CapMonster Cloud,那么在这些服务的文档中,在专门介绍验证码类型的部分,通常会说明哪些参数是动态的,以及它们是在代码的哪个位置生成的。要提取这些值,并随后使用它们来使用服务解决验证码问题,所有这些都是必要的。此外,掌握使用开发人员工具的基本技能对于快速找到必要参数的值也非常有用。
首先,让我们来定义生成此类参数的主要方法:
- 使用 JavaScript(客户端
当您打开带有验证码的页面时,会加载一个脚本来跟踪您的操作--鼠标移动、点击、按键。JavaScript 会生成参数--一些元素和表单、中间验证窗口(如 Cloudflare Challenge 的情况)、随机数、与您的交互有关的数据以及设备信息。
- 使用 API(服务器端)
在处理验证码请求时,服务器可以添加有用的参数,例如会话 ID 或散列值。API 还可以返回创建新验证码会话所需的参数--每次尝试时,服务器都会自动更新这些参数。
为清楚起见,让我们同时考虑这两种方法。举例来说,亚马逊的验证码通过 JavaScript 生成上下文,而 GeeTest v.3 则通过 API 生成挑战密钥
亚马逊(AWS WAF)
在这种验证码类型中,重要参数(包括不断变化的上下文)是通过一个特殊的客户端保护脚本加载的:
Amazon (AWS WAF)
在这种验证码类型中,重要参数(包括不断变化的上下文)是通过一个特殊的客户端保护脚本加载的。

在这里,验证码参数是通过 API 生成的,您可以在 "网络 "选项卡的请求中跟踪所需的 URL:
您可以使用 "开发者工具 "在登陆页面的元素中找到它。

您可以通过分析浏览器和服务器之间的请求和响应来确定必要的参数。以下是主要方法和步骤:
- 开发工具:
- 打开一个带有验证码的网页;
- 转到 "网络 "选项卡;
- 查找与验证码相关的查询(通常是对验证码服务器的请求,例如 api.geetest.com 等);
- 检查这些请求中传递的参数,例如:?t=123456789123;
- 比较多个查询;
- 多次刷新页面;
- 比较参数。如果值在不同请求之间发生变化,则说明它们是动态的;
- 查找 JavaScript 调用
- 在 DevTools 中的 "Sources "或 "Elements "选项卡下查找。检查连接了哪些脚本;
- 查找参数生成,如时间戳、上下文、挑战等;
- 查找关键字:JavaScript 代码通常使用函数生成动态参数;
9.分析服务器请求。有些参数由服务器生成。这些数据必须保存并在下一次查询中使用。
- 用于分析的嗅探器和代理服务器
这些工具(如 Charles Proxy)允许您拦截请求、查找动态参数和测试更改,帮助您了解其逻辑,并检查服务器如何处理修改后的请求。
这些工具的工作包括:
- 这些工具记录向验证码服务器发出的请求(例如,参数 t、challenge、context)。
- 检查报头、URL 参数、请求正文和 cookie,以确定关键值、
- 更改参数(如令牌)以检查它们对服务器响应的影响。
使用 Charles Proxy 分析验证码参数的快速指南:
- 下载并安装 Charles Proxy。
- 通过代理→ SSL 代理设置启用 SSL 代理....添加验证码域
- 使用加载验证码的页面启动 Charles 和浏览器。
- 转到页面开始记录请求。
- 在结构选项卡中,找到对验证码服务的请求(例如,www.google.com/recaptcha/api.js)。
- 打开请求/响应,检查其中传递的参数(令牌、网站密钥、挑战、cookie 等)。
分析验证码数据并结合其他工具自动解决验证码问题的另一种方法是浏览器模拟器,例如 Selenium、Puppeteer 和 Playwright。
自动化。所有这三种工具都允许您管理浏览器,执行常见的用户操作:点击、文本输入、页面导航等。所有这些都可以自动完成
支持处理动态内容. Selenium、Puppeteer 和 Playwright 可与 JavaScript 协同工作,因此您可以处理动态加载的页面元素。 它们被广泛用于自动测试各种 Web 应用程序。
等待项目。您可以设置等待元素加载 - 这允许您在页面加载完成后捕获数据。
分析答案。允许您拦截网络请求,查看来自 API 的数据变化。
脚本访问。使用内置工具(如 Puppeteer),您可以执行 JavaScript 从动态加载的元素中提取信息。
硒
截取 DOM 元素
使用 find_element_by_xpath 或 find_element_by_css_selector 方法访问与验证码相关的值。
脚本 JavaScript
使用 driver.execute_script() 直接执行 JavaScript。
通过代理记录请求
与 BrowserMob 代理集成以分析网络流量。
您可以提取头、请求体、令牌和验证码参数。
Puppeteer
拦截请求和响应
使用 page.on('request') 和 page.on('response') 捕获网络流量。
动态 DOM 值
使用 page.evaluate() 等方法分析页面级别的参数。
Playwright
网络请求
page.on('request') 和 page.on('response') 监控网络数据。
分析 DOM
page.locate() 从元素中提取数据。
执行 JavaScript
使用 page.evaluate() 从脚本中解析和提取参数。
使用 CapMonster 云
一旦您分析并找到了所有必要的验证码参数,下一步就是使用 CapMonster 云创建并向服务器发送任务,以自动解决验证码问题。将该工具集成到你的代码中非常简单。它支持 Python、JavaScript、C#、Go 和 PHP 等编程语言。您只需选择适当的语言并安装 官方库即可使用它。
- 要开始使用,请注册 CapMonster 云并获取访问其服务的 API 密钥。
- 安装库
对于 Python,通过 pip 安装官方库:
pip install capmonstercloudclient
3. 在代码中创建一个任务来解决验证码问题并获得解决方案。Python 示例:
导入 asyncio
from capmonstercloudclient import CapMonsterClient, ClientOptions
from capmonstercloudclient.requests import RecaptchaV2ProxylessRequest
client_options = ClientOptions(api_key=<YOUR_API_KEY>)
cap_monster_client = CapMonsterClient(options=client_options)
async def solve_captcha():
return await cap_monster_client.solve_captcha(recaptcha2request)
recaptcha2request = RecaptchaV2ProxylessRequest(websiteUrl="https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high"、
websiteKey="6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd")
responses = asyncio.run(solve_captcha())
print(responses)
代码>
4.收到决定后,将其发送到需要确认的表单中的网页。您可以根据验证码的类型设置代理、使用无代理解决方案和其他参数。
提示:对于复杂的验证码(例如 DataDome 或 Geetest),请使用自定义任务
为了演示示例,我们将使用 GeeTest v.3、Cloudflare Challenge 和 Amazon (AWS WAF) 测试类型。
这种类型的验证码包含向 CapMonster 云服务器创建请求所需的动态参数。参数通过 API 生成,使用的 URL 如下:https://example.com/api/v1/gee-test/init-params?t=${t}。同时,浏览器自动化不需要额外的工具 - 您可以使用内置的 Fetch(JavaScript)或 requests(Python)和 Newtonsoft.Json (C#)库。CapMonster Cloud 文档中提供了所有参数的列表。
JavaScript
// 导入必要的依赖项
const { CapMonsterCloudClientFactory, ClientOptions, GeeTestProxylessRequest } = require('@zennolol.com).= require('@zennolab_com/capmonstercloud-client');
async function run() {
// 创建 CapMonster 云客户端
const cmcClient = CapMonsterCloudClientFactory.Create(new ClientOptions({
clientKey: 'your_api_key', // 替换为您的 API 密钥 CapMonsterCloud
}));
// 通过 API 获取验证码参数 const t = new Date().getTime();
const response = await fetch(`https://example.com/api/v1/gee-test/init-params?t=${t}`); // 通过 API 获取 GeeTest 验证码的动态参数。请确保您使用的 URL 与实际情况相符
const data = await response.json();
const { challenge, gt }= data;
const geeTestProxylessRequest = new GeeTestProxylessRequest({
websiteURL:'https://example.com', // 包含验证码的页面 URL
gt: gt, // 通过 API 获取的 gt 参数
challenge: challenge // 通过 API 获取的验证码参数
});
const solutionResponse = await cmcClient.Solve(geeTestProxylessRequest);
如果 (!solutionResponse || !solutionResponse.solution) {
throw new Error('Captcha not solved.');
}
Python
# 导入必要的依赖项
导入请求
导入 asyncio
导入时间
from capmonstercloudclient import CapMonsterClient, ClientOptions
from capmonstercloudclient.requests import GeetestProxylessRequest
async def run():
# 创建客户端 CapMonster Cloud
client_options = ClientOptions(api_key='your_api_key') # 替换为您的 API 密钥 CapMonsterCloud
cmc_client = CapMonsterClient(options=client_options)
# 通过 API 获取验证码参数
t = int(time.time() * 1000) # 以毫秒为单位获取当前时间戳
response = requests.get(f'https://example.com/api/v1/gee-test/init-params?t={t}')
data = response.json()
challenge = data.get('challenge')
gt = data.get('gt')
if not challenge or not gt:
raise ValueError('Failed to get parameters for captcha.')
# 创建一个请求来解决验证码问题 gee_test_proxyless_request = GeetestProxylessRequest(
websiteUrl='https://example.com', # 包含验证码的页面URL
gt=gt、
challenge=challenge
)
# 发送验证码解决方案请求
solution_response = await cmc_client.solve_captcha(gee_test_proxyless_request)
if not solution_response or not solution_response:
raise ValueError('Captcha not solved.')
print('Captcha solved:', solution_response)
asyncio.run(run())
C#
/ 导入 CapMonster 云库和必要的依赖项
使用 Zennolab.CapMonsterCloud.Requests;
使用 Zennolab.CapMonsterCloud.Requests; 使用 Zennolab.CapMonsterCloud.Json
使用 Newtonsoft.Json;
类
{
static async Task Main(string[] args)
{
// 使用您的 CapMonster 云 API 密钥设置客户端
var clientOptions = new ClientOptions
{
ClientKey = "your_api_key" // 替换为您的 CapMonster 云 API 密钥
};
// 使用指定的设置创建一个 CapMonster 云客户端 var cmCloudClient = CapMonsterCloudClientFactory.Create(clientOptions);
// 创建 HTTP 客户端,使用它发送请求 var httpClient = new HttpClient();
// 获取请求的当前时间戳
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
// 生成用于获取 GeeTest 验证码动态参数的 URL
var requestUrl = $"https://example.com/api/v1/captcha/gee-test/init-params?t={timestamp}";
// 以字符串形式发送请求并获取响应
var response = await httpClient.GetStringAsync(requestUrl);
dynamic data = JsonConvert.DeserializeObject(response);
// 利用获取的参数创建查询以解决 GeeTest 验证码问题
var geetestRequest = new GeeTestProxylessRequest
{
WebsiteUrl = "https://example.com/demo/geetest", // 包含验证码的页面 URL Gt = data.gt, // 从响应中获得的 gt 参数
Challenge = data.challenge // 从响应中导出的验证码参数
};
// 发送验证码请求并获取结果
var geetestResult = await cmCloudClient.SolveAsync(geetestRequest);
Console.WriteLine($"Captcha Solution:\nChallenge: {geetestResult.Solution.Challenge}\nValidate: {geetestResult.Solution.Validate}\nSecCode: {geetestResult.Solution.SecCode}");
}
}
要使用这种类型的检查,您需要使用浏览器模拟器来正确显示动态内容,并为检查挑战页面打开一个特殊窗口。动态参数通过 window.turnstile 生成,我们将使用内置 JavaScript 对其进行拦截。然后使用这些参数形成对 CapMonster 云服务器的请求。让我们考虑两种方法--获取令牌和 cf-clearance cookie,然后将其插入浏览器,从而确认决定是否成功。CapMonster Cloud 文档中列出了所有必要参数的列表。
JavaScript
// 导入 CapMonster 云计算库
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const { CapMonsterCloudClientFactory, ClientOptions, TurnstileRequest }= require('@zennolab_com/capmonstercloud-client');
(async function example() {
// 为 Chrome 浏览器创建设置对象
const options = new chrome.Options();
// 为 Chrome 浏览器创建并运行驱动程序
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options) // 为 Chrome 浏览器进行设置
.build();
let params = null; // 用于存储验证码参数的变量
try {
while (!params) {
// 打开带有验证码的页面
await driver.get('https://example.com'); // 带有验证码的页面的 URL
// 在页面上执行 JavaScript 以获取验证码参数
await driver.executeScript(`)
// 拦截对 turnstile 对象中 render 函数的调用,以获取参数
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === 'render') {
// 重写 render 函数以获取验证码参数
return function(a, b) {
让 p = {
websiteKey: b.sitekey, // 网站密钥
websiteURL: window.location.href, // 验证码页面的 URL
data: b.cData、
pagedata: b.chlPageData、
action: b.action、
userAgent: navigator.userAgent
};
console.log(JSON.stringify(p)); // 将参数输出到控制台以便调试
window.params = p; // 将参数保存到全局变量中
window.turnstileCallback = b.callback; // 保存回调函数
return target.render.apply(this, arguments); // 调用原始渲染函数
}
}
return target[prop]; // 返回对象的其余属性
}
});
`);
// 从全局变量 window.params 获取参数
params = await driver.executeAsyncScript(`)
const callback = arguments[arguments.length - 1]; // 获取要完成的回调
setTimeout(() => {
callback(window.params); // 通过回调传递参数
}, 5000);
`);
如果 (!params) {
console.log('Parameters are not received, reload the page...');
await driver.sleep(3000);
}
}
console.log('Options:', params); // 显示获得的参数
// 使用 API 密钥创建 CapMonster 云客户端
const cmcClient = CapMonsterCloudClientFactory.Create(new ClientOptions({
clientKey: 'your_api_key', // 替换为您的 API 密钥 CapMonster Cloud
}));
// 使用接收到的参数创建一个用于解决 Turnstile 验证码的请求
const turnstileRequest = new TurnstileRequest({
websiteURL: params.websiteURL、
websiteKey: params.websiteKey、
data: params.data、
action: params.action、
cloudflareTaskType:token'、
pageAction: 'managed'、
pageData: params.pagedata
});
// 发送验证码解决方案请求
const response = await cmcClient.Solve(turnstileRequest);
// 检查验证码是否已解决
if (!response || !response.solution) {
throw new Error('Captcha not solved.');
}
console.log('Captcha solved:', response.solution); // 显示验证码的解决方案
// 在页面上执行 JavaScript,将收到的令牌传递给回调函数ю
await driver.executeScript(`
window.turnstileCallback('${response.solution.token}'); // 将验证码解决方案令牌传递给回调函数
`);
} catch (err) {
console.error('Error:', err);
} finally {
await driver.quit();
}
})();
Python
# 导入必要的依赖项
导入 asyncio
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.options import Options
from capmonstercloudclient import CapMonsterClient, ClientOptions
from capmonstercloudclient.requests import TurnstileProxylessRequest
# 使用 API 密钥设置 CapMonsterCloud
client_options = ClientOptions(api_key="your_api_key") # 替换为您的 API 密钥 CapMonsterCloud
cap_monster_client = CapMonsterClient(options=client_options)
# 获取验证码参数的函数
async def get_turnstile_params(driver):
params = None # 用于存储验证码参数的变量
while not params:
driver.get("https://example.com") # 用验证码打开网页
# 执行 JavaScript 代码以拦截呈现函数并提取参数
driver.execute_script("""
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === 'render') {
// 重写 render 函数以捕获验证码参数
return function(a, b) {
让 p = {
websiteKey: b.sitekey, // 网站密钥
websiteURL: window.location.href, // 验证码页面的 URL
data: b.cData、
pagedata: b.chlPageData、
action: b.action、
userAgent: navigator.userAgent
};
console.log(JSON.stringify(p));
window.params = p; // 将参数保存到全局变量中
window.turnstileCallback = b.callback; // 保存回调函数
return target.render.apply(this, arguments); // 调用原始函数 render
};
}
return target[prop]; // 返回对象的其余属性
}
});
""")
# 通过 execute_async_script 从全局变量 `window.params` 中提取参数
params = driver.execute_async_script(""")
const callback = arguments[arguments.length - 1]; // 获取要完成的回调
setTimeout(() => {
callback(window.params); // 通过回调传递参数
}, 5000);
""")
if not params:
print("Parameters are not received, reload the page...")
await asyncio.sleep(3)
return params # 返回收到的参数
async def solve_turnstile(params):
# 使用 CapMonsterCloud 创建一个验证码求解请求
request = TurnstileProxylessRequest(
websiteURL=params["websiteURL"]、
websiteKey=params["websiteKey"]、
data=params["data"]、
action=params["action"]、
pageAction="managed"、
cloudflareTaskType="token"、
pageData=params["pagedata"]、
userAgent=params["userAgent"]
)
# 发送请求以解决验证码问题并获取令牌
response = await cap_monster_client.solve_captcha(request)
return response["token"]
async def main():
chrome_options = Options()
driver = webdriver.Chrome(service=ChromeService(), options=chrome_options)
try:
# 获取验证码参数
params = await get_turnstile_params(driver)
print("Parameters received:", params)
# 解决验证码问题并获取令牌
token = await solve_turnstile(params)
print("Captcha solved. Token:", token)
# 执行 JavaScript,将令牌传递给回调函数
driver.execute_script(f "window.turnstileCallback('{token}');")
except Exception as e:
# 如果出现错误,我们将进行处理
print(f "Error: {e}")
最后
await asyncio.sleep(5)
driver.quit()
asyncio.run(main())
C#
// 导入必要的依赖项
使用 OpenQA.Selenium;
使用 OpenQA.Selenium.Chrome;
使用 Zennolab.CapMonsterCloud;
使用 Zennolab.CapMonsterCloud.Requests;
类
{
static async Task Main(string[] args)
{
// 使用 API 密钥进行 CapMonster 云设置
var clientOptions = new ClientOptions
{
ClientKey = "your_api_key" // 替换为您的 CapMonster 云 API 密钥
};
// 创建与 CapMonster Cloud 协同工作的客户端
var cmCloudClient = CapMonsterCloudClientFactory.Create(clientOptions);
// ChromeDriver 设置
var chromeOptions = new ChromeOptions();
// 初始化 Chrome 驱动程序
using var driver = new ChromeDriver(chromeOptions);
// 获取验证码参数
var paramsObtained = await GetTurnstileParams(driver);
Console.WriteLine("Parameters received:" + string.Join(", ", paramsObtained));
// 创建验证码解决方案请求
var turnstileRequest = new TurnstileProxylessRequest
{
WebsiteUrl = paramsObtained["websiteURL"].ToString()、
WebsiteKey = paramsObtained["websiteKey"].ToString()、
Data = paramsObtained["data"].ToString()、
PageAction = paramsObtained["pageAction"].ToString()、
CloudflareTaskType = "token"、
PageData = paramsObtained["pagedata"].ToString()、
UserAgent = paramsObtained["userAgent"].ToString()
};
// 使用 CapMonster 云的验证码解决方案
var turnstileResult = await cmCloudClient.SolveAsync(turnstileRequest);
Console.WriteLine("Captch solved. Token: " + turnstileResult.Solution.Value);
// 将令牌传递给页面上的回调函数
((IJavaScriptExecutor)driver).ExecuteScript($"window.turnstileCallback('{turnstileResult.Solution.Value}');");
await Task.Delay(5000);
}
// 获取验证码参数的函数
static async Task<Dictionary<string, object>> GetTurnstileParams(IWebDriver driver)
{
Dictionary<string, object> paramsObtained = null; // 用于存储参数的变量
while (paramsObtained == null) // 重复直到获得参数
{
driver.Navigate().GoToUrl("https://example.com"); // 打开验证码页面
// 执行 JavaScript 以拦截验证码参数
((IJavaScriptExecutor)driver).ExecuteScript(@")
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === 'render') {
// 重写 render 函数以提取参数
return function(a, b) {
让 p = {
websiteURL: window.location.href、
websiteKey: b.sitekey、
data: b.cData、
pageAction: b.action、
pagedata: b.chlPageData、
userAgent: navigator.userAgent
};
console.log(JSON.stringify(p));
window.params = p; // 将参数保存到全局变量中
window.turnstileCallback = b.callback; // 保存回调函数
return target.render.apply(this, arguments); // 调用原始呈现函数
};
}
return target[prop]; // 返回对象的其余属性
}
});
");
// 通过 ExecuteAsyncScript 从全局变量 "window.params "中提取参数
paramsObtained = await Task.Run(() =>;
{
return (Dictionary<string, object>)((IJavaScriptExecutor)driver).ExecuteAsyncScript(@").
const callback = arguments[arguments.length - 1]; // 回调以完成执行
setTimeout(() => {
callback(window.params); // 通过回调传递参数
}, 5000);
");
});
// 如果未获得参数,请稍候再试
if (paramsObtained == null)
{
Console.WriteLine("Parameters are not received, reload the page...");
await Task.Delay(3000);
}
}
return paramsObtained; // 返回收到的参数
}
}
JavaScript
// 导入必要的依赖项
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const { CapMonsterCloudClientFactory, ClientOptions, TurnstileRequest }= require('@zennolab_com/capmonstercloud-client');
(async function example() {
// 设置 ChromeDriver
const options = new chrome.Options();
// 为 sChrome 初始化 WebDriver
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
let params = null; // 用于存储验证码参数的变量
let htmlPageBase64 = ''; // 用于以 Base64 格式存储页面的变量
try {
while (!params) {
// 用验证码打开页面
await driver.get('https://example.com'); // 替换为页面 URL
// 运行脚本以拦截验证码的参数
await driver.executeScript(`)
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === 'render') {
// 重写 render 函数以提取参数
return function(a, b) {
让 p = {
websiteKey: b.sitekey、
websiteURL: window.location.href
};
console.log(JSON.stringify(p));
window.params = p; // 将参数保存到全局变量中
return target.render.apply(this, arguments); //调用原始呈现函数 }
}
return target[prop]; // 返回对象的其余属性
}
});
`);
// 使用 "window.params "全局变量提取参数
params = await driver.executeAsyncScript(`)
const callback = arguments[arguments.length - 1];
setTimeout(() => {
callback(window.params); // 通过回调返回参数
}, 5000);
`);
如果 (!params) {
console.log('Parameters are not received, reload the page...');
await driver.sleep(3000); }
}
console.log('Captcha parameters:', params);
// 获取页面的 HTML 代码并进行 Base64 编码
const pageSource = await driver.getPageSource();
htmlPageBase64 = Buffer.from(pageSource).toString('base64');
// CapMonster 云客户端供应
const cmcClient = CapMonsterCloudClientFactory.Create(new ClientOptions({
clientKey: 'your_api_key', // 替换为您的 CapMonster 云 API 密钥
}));
// 生成验证码请求
const turnstileRequest = new TurnstileRequest({
websiteURL: params.websiteURL、
websiteKey: params.websiteKey、
cloudflareTaskType:cf_clearance'、
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'、
htmlPageBase64: htmlPageBase64、
proxyType:http'、
proxyAddress:'8.8.8.8',
proxyPort: 8000、
proxyLogin:proxyLogin: 'proxyLoginHere'、
proxyPassword: 'proxyPasswordHere'.
});
// 使用 CapMonster 云解决验证码问题
const response = await cmcClient.Solve(turnstileRequest);
if (!response || !response.solution) {
throw new Error('Captcha not solved.');
}
console.log('Captcha solved, cookie cf_clearance:', response.solution);
} catch (err) {
console.error('Error:', err);
} finally {
await driver.quit();
}
})();
Python
# 导入必要的依赖项
导入 asyncio
导入 base64
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.options import Options
from capmonstercloudclient import CapMonsterClient, ClientOptions
from capmonstercloudclient.requests import TurnstileRequest
# 设置 CapMonster 云客户端
client_options = ClientOptions(api_key="your_api_key") # 替换为您的 CapMonsterCloud API 密钥
cap_monster_client = CapMonsterClient(options=client_options)
# 获取转门参数的函数
async def get_turnstile_params(driver):
params = None
while not params:
# 加载带有验证码的页面
driver.get("https://example.com") # 指定带有验证码的页面的 URL
# 执行脚本截取验证码参数
driver.execute_script("""
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === 'render') {
// 重写 render 方法以提取参数
return function(a, b) {
让 p = {
websiteKey: b.sitekey、
websiteURL: window.location.href
};
console.log(JSON.stringify(p));
window.params = p; // 将参数保存为全局变量
return target.render.apply(this, arguments);
};
}
return target[prop]; // 返回对象的其余属性
}
});
""")
# 使用异步脚本提取参数
params = driver.execute_async_script(""")
const callback = arguments[arguments.length - 1];
setTimeout(() => {
callback(window.params || null); // 返回参数或 null
}, 5000);
""")
if not params:
print("Parameters are not received, reload the page...")
await asyncio.sleep(3) # 等待后再试一次
返回参数
# 解决验证码的函数
async def solve_turnstile(params, html_page_base64):
request = TurnstileRequest(
websiteURL=params["websiteURL"]、
websiteKey=params["websiteKey"]、
cloudflareTaskType="cf_clearance"、
userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"、
htmlPageBase64=html_page_base64、
proxyType="http"、
proxyAddress="8.8.8.8",
proxyPort=8000、
proxyLogin="proxyLoginHere"、
proxyPassword="proxyPasswordHere")
)
# 发送验证码解决方案请求
response = await cap_monster_client.solve_captcha(request)
print("Answer CapMonster:", response)
如果响应中没有 "cf_clearance",则
raise Exception("验证码未解决。")
return response["cf_clearance"] 返回响应["cf_clearance"]。
async def main():
chrome_options = Options()
driver = webdriver.Chrome(service=ChromeService(), options=chrome_options)
try:
# 获取转台参数
params = await get_turnstile_params(driver)
print("Captcha parameters received", params)
# 以 Base64 编码 HTML 页面
page_source = driver.page_source
html_page_base64 = base64.b64encode(page_source.encode("utf-8")).decode("utf-8")
print("The HTML of the page is encoded in Base64.")
# 解决验证码问题
cf_clearance = await solve_turnstile(params, html_page_base64)
print("Captch solved. Cookie cf_clearance:", cf_clearance)
except Exception as e:
print(f "Error: {e}")
最后
await asyncio.sleep(5)
driver.quit()
asyncio.run(main())
C# JavaScript Python C# 使用动态参数和自动验证码解题时,经常会遇到一些复杂问题,例如区块、验证码或动态更新的页面元素。以下是成功解决此类限制的实用技巧。 标准 Selenium WebDriver 标识符很容易被安全系统检测到。要最大限度降低阻止的可能性: 安装 undetected_chromedriver 库。它会自动屏蔽 WebDriver 的使用: 使用示例: 启用无头浏览器模式可进一步减少怀疑。 2.模拟用户操作 过于 "机械 "的脚本可能会引起怀疑。请使用以下技术: 鼠标移动:使用 pyautogui 或 selenium-wire 等库模拟鼠标操作 3.使用代理服务器 代理可帮助您避免被 IP 地址阻止: 使用代理轮换。请注意代理的地理位置,以便与网站所在区域相匹配: 4.更新用户代理和头信息 因此,在不阻塞的情况下长期工作的提示: 使用动态验证码参数是一个令人兴奋的过程,可以让您更好地了解网络保护机制是如何工作的。在本文中,我们详细分析了要点:从如何识别和分析动态参数,到如何提取这些参数并有效地解决验证码问题。 我们还展示了各种编程语言的代码示例,以便您可以轻松学习如何提取所需数值,并使用 CapMonster Cloud 自动解决验证码问题。使用 Selenium、Puppeteer、Playwright、Undetected ChromeDriver、高质量代理、User-Agent 旋转和用户行为模拟等解决方案,您将有机会解决许多限制。 同时,重要的是要记住请求的频率,并遵守网络资源的使用规则,这样您的自动化不仅有效,而且合乎道德。祝您在实施想法和新项目时好运! 注意:我们在此提醒您,该产品用于在您自己的网站和您拥有合法访问权限的网站上进行自动化测试。// 导入必要的依赖项
使用 OpenQA.Selenium;
使用 OpenQA.Selenium.Chrome;
使用 Zennolab.CapMonsterCloud;
使用 Zennolab.CapMonsterCloud.Requests;
类
{
static async Task Main(string[] args)
{
// 客户端设置 CapMonster 云
var clientOptions = new ClientOptions
{
ClientKey = "your_api_key" // 替换为您的 CapMonsterCloud API 密钥
};
var cmCloudClient = CapMonsterCloudClientFactory.Create(clientOptions);
// 设置 ChromeDriver
var chromeOptions = new ChromeOptions();
using var driver = new ChromeDriver(chromeOptions);
尝试
{
// 获取转门参数
var paramsObtained = await GetTurnstileParams(driver);
Console.WriteLine("Parameters received:" + string.Join(", ", paramsObtained));
// 创建一个请求以解决验证码问题
var turnstileRequest = new TurnstileRequest
{
WebsiteUrl = paramsObtained["websiteURL"].ToString()、
WebsiteKey = paramsObtained["websiteKey"].ToString()、
CloudflareTaskType = "cf_clearance"、
NoCache = false、
ProxyType = ProxyType.Http、
ProxyAddress = "8.8.8.8"、
代理端口 = 8000、
代理登录 = "proxyLoginHere"、
代理密码 = "proxyPasswordHere"、
PageData = paramsObtained["pagedata"].ToString()、
数据 = paramsObtained["data"].ToString()、
HtmlPageBase64 = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(driver.PageSource)), // 编码 HTML 页面
UserAgent = paramsObtained["userAgent"].ToString()
};
// 向 CapMonster 云发送请求
var turnstileResult = await cmCloudClient.SolveAsync(turnstileRequest);
Console.WriteLine("Captcha solved.Cookie cf_clearance:" + turnstileResult.Solution.Clearance);
// 如有必要,在浏览器 cookie 中添加 cf_clearance
// var cfClearance = turnstileResult.Solution.Clearance;
// driver.Manage().Cookies.AddCookie(new Cookie("cf_clearance", cfClearance));
// 如果需要回调 callback,请通过 JavaScript 设置
// ((IJavaScriptExecutor)driver).ExecuteScript($"window.turnstileCallback('{cfClearance}');");
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
最后
{
await Task.Delay(5000);
driver.Quit();
}
}
// 获取旋转门参数的函数
static async Task<Dictionary<string, object>> GetTurnstileParams(IWebDriver driver)
{
Dictionary<string, object> paramsObtained = null;
while (paramsObtained == null)
{
// 打开转门页面
driver.Navigate().GoToUrl("https://example.com"); // 指定带有验证码的 URL
// 使用 JavaScript 替换呈现方法
((IJavaScriptExecutor)driver).ExecuteScript(@")
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === 'render') {
return function(a, b) {
让 p = {
websiteURL: window.location.href、
websiteKey: b.sitekey、
pagedata: b.chlPageData、
data: b.cData、
userAgent: navigator.userAgent
};
console.log(JSON.stringify(p));
window.params = p;
window.turnstileCallback = b.callback; // 保存回调以备后续调用
return target.render.apply(this, arguments);
};
}
return target[prop];
}
});
");
paramsObtained = await Task.Run(() =>;
{
return (Dictionary<string, object>)((IJavaScriptExecutor)driver).ExecuteAsyncScript(@").
const callback = arguments[arguments.length - 1];
setTimeout(() => {
callback(window.params); // 返回存在的参数
}, 5000);
");
});
如果 (paramsObtained == null)
{
Console.WriteLine("Parameters not received, page reload...");
await Task.Delay(3000);
}
}
return paramsObtained;
}
}
// 导入必要的依赖项
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const { CapMonsterCloudClientFactory, ClientOptions, AmazonProxylessRequest }= require('@zennolab_com/capmonstercloud-client');
(async function run() {
// 为 Chrome 浏览器设置
const options = new chrome.Options();
// options.addArguments('--headless'); // 如果想在后台运行,请添加
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
const pageUrl = 'https://example.com'; // 提供带有验证码的页面 URL
await driver.get(pageUrl);
// 使用 JavaScript 获取验证码参数
const captchaParams = await driver.executeScript(() => {
const gokuProps = window.gokuProps || {}; // 如果存在,获取 gokuProps 对象
const scripts = Array.from(document.querySelectorAll('script')); // 收集所有标签<script>;
返回 {
websiteKey: gokuProps.key || "Not found"、
context: gokuProps.context || "Not found"、
iv: gokuProps.iv || "未找到"、
challengeScriptUrl: scripts.find(script => script.src.includes('challenge.js'))?.src || "未找到"、
captchaScriptUrl: scripts.find(script => script.src.includes('captcha.js'))?.src || "未找到".
};
});
console.log('Obtained parameters:', captchaParams);
// 设置 CapMonster 云客户端
const cmcClient = CapMonsterCloudClientFactory.Create(new ClientOptions({
clientKey: 'your_api_key', // 替换为您的 API 密钥
}));
// 创建验证码解决方案请求
const amazonProxylessRequest = new AmazonProxylessRequest({
websiteURL: pageUrl、
challengeScript: captchaParams.challengeScriptUrl、
captchaScript: captchaParams.captchaScriptUrl、
websiteKey: captchaParams.websiteKey、
context:captchaParams.context、
iv: captchaParams.iv、
cookieSolution: false, // 如果你想接收 cookie,请将其设置为 true
});
try {
// 通过 CapMonster 云提供验证码解决方案
const response = await cmcClient.Solve(amazonProxylessRequest);
if (!response?.solution) throw new Error('CAPTCHA not solved.');
console.log('CAPTCHA solved:', response.solution);
} catch (err) {
console.error('Error in solving CAPTCHA:', err);
} finally {
await driver.quit();
}
})()
.then(() => {
console.log('DONE');
process.exit(0);
})
.catch(err => {
console.error('ERROR:', err);
process.exit(1);
});
# 导入所需的依赖关系
导入 asyncio
from capmonstercloudclient import CapMonsterClient, ClientOptions
from capmonstercloudclient.requests import AmazonWafProxylessRequest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
captcha_url = "https://example.com" # 输入您想要的 URL
# 配置 ChromeDriver
chrome_options = Options()
# chrome_options.add_argument('--headless') # 为后台工作删除注释
driver = webdriver.Chrome(options=chrome_options)
def get_captcha_params():
"""
通过 JavaScript 从页面获取验证码参数。
"""
driver.get(CAPTCHA_URL)
captcha_params = driver.execute_script("""
const gokuProps = window.gokuProps || {}; // 通过 JavaScript 获取 gokuProps。
const scripts = Array.from(document.querySelectorAll('script')); // 页面上的所有内容
返回 {
websiteKey: gokuProps.key || "Not found"、
context: gokuProps.context || "Not found"、
iv: gokuProps.iv || "未找到"、
challengeScriptUrl: scripts.find(script => script.src.includes('challenge.js'))?.src || "未找到"、
captchaScriptUrl: scripts.find(script => script.src.includes('captcha.js'))?.src || "未找到".
};
""")
返回 captcha_params
# CapMonsterCloud 设置
client_options = ClientOptions(api_key="your_api_key") # 替换为您的 API 密钥
cap_monster_client = CapMonsterClient(options=client_options)
async def solve_captcha(captcha_params):
"""
为 CapMonsterCloud 创建一个请求并发送,以解决验证码问题。
"""
amazon_waf_request = AmazonWafProxylessRequest(
websiteUrl=CAPTCHA_URL、
challengeScript=captcha_params["challengeScriptUrl"]、
captchaScript=captcha_params["captchaScriptUrl"]、
websiteKey=captcha_params["websiteKey"]、
context=captcha_params["context"]、
iv=captcha_params["iv"]、
cookieSolution=False # 如果需要 cookie 解决方案,请指定为 True
)
return await cap_monster_client.solve_captcha(amazon_waf_request)
async def main():
try:
# 提取验证码参数
captcha_params = get_captcha_params()
print("Options CAPTCHA:", captcha_params)
# 验证码解决方案
response = await solve_captcha(captcha_params)
print("Result of the solution CAPTCHA:", response)
except Exception as e:
print("An error has occurred:", e)
最后
driver.quit()
asyncio.run(main())
使用 OpenQA.Selenium;
使用 OpenQA.Selenium.Chrome;
使用 Zennolab.CapMonsterCloud;
使用 Zennolab.CapMonsterCloud.Requests;
类
{
static async Task Main(string[] args)
{
const string CAPTCHA_URL = "https://example.com"; // URL with CAPTCHA
// ChromeDriver 设置
var chromeOptions = new ChromeOptions();
// chromeOptions.AddArgument("--headless"); // 为后台工作删除注释
using var driver = new ChromeDriver(chromeOptions);
// 提取验证码参数
var captchaParams = GetCaptchaParams(driver, CAPTCHA_URL);
// CapMonster 云设置
var clientOptions = new ClientOptions
{
ClientKey = "your_api_key" // 替换为您的 CapMonster 云 API 密钥
};
var cmCloudClient = CapMonsterCloudClientFactory.Create(clientOptions);
// 创建请求
var amazonWafRequest = new AmazonWafProxylessRequest
{
WebsiteUrl = CAPTCHA_URL、
ChallengeScript = captchaParams["challengeScriptUrl"]、
CaptchaScript = captchaParams["captchaScriptUrl"]、
WebsiteKey = captchaParams["websiteKey"]、
Context = captchaParams["context"]、
Iv = captchaParams["iv"]、
CookieSolution = false
};
// 提交解决方案请求
var solveResult = await cmCloudClient.SolveAsync(amazonWafRequest);
// 输出结果
Console.WriteLine("ExistingToken: " + solveResult.Solution.ExistingToken);
Console.WriteLine("CaptchaVoucher: " + solveResult.Solution.CaptchaVoucher);
}
private static Dictionary<string, string> GetCaptchaParams(IWebDriver driver, string url)
{
driver.Navigate().GoToUrl(url);
var jsExecutor = (IJavaScriptExecutor)driver;
// 执行 JavaScript 以提取参数 var captchaParams = jsExecutor.ExecuteScript(@"
const gokuProps = window.gokuProps || {};
const scripts = Array.from(document.querySelectorAll('script'));
返回 {
websiteKey: gokuProps.key || 'Not found'、
context: gokuProps.context || 'Not found'、
iv: gokuProps.iv || '未找到'、
challengeScriptUrl: scripts.find(script => script.src.includes('challenge.js'))?.src || '未找到'、
captchaScriptUrl: scripts.find(script => script.src.includes('captcha.js')?.src || 'Not found'.
};
") as IDictionary<string, object>;
return captchaParams.ToDictionary(k => k.Key, v => v.Value?.ToString() ??"未找到");
}
}
pip install undetected-chromedriver
import undetected_chromedriver.v2 as uc
options = uc.ChromeOptions()
options.add_argument("--headless") # 在后台运行
options.add_argument("--disable-blink-features=AutomationControlled")
driver = uc.Chrome(options=options)
driver.get("https://example.com")
print(driver.page_source)
driver.quit()
<代码导入时间
导入随机
time.sleep(random.uniform(1, 3)) # 1 到 3 秒的延迟时间
。driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")
从 selenium.webdriver.common.proxy 导入 Proxy, ProxyType
proxy = Proxy()
proxy.proxy_type = ProxyType.MANUAL
proxy.http_proxy = "http://username:password@proxy_ip:port"
capabilities = webdriver.DesiredCapabilities.CHROME
proxy.add_too_capabilities(capabilities)
driver = webdriver.Chrome(desired_capabilities=capabilities)
options。add_argument("user-agent=Your User-Agent")