Parâmetros dinâmicos do CAPTCHA: O que são, como identificá-los e extraí-los. Solução bem-sucedida de CAPTCHAs com dados dinâmicos
Atualmente, é difícil imaginar recursos modernos da Web sem determinados mecanismos de proteção, como o CAPTCHA, projetado para verificar se um visitante é um ser humano real e não um bot que representa uma ameaça em potencial. No passado, esses eram principalmente CAPTCHAs baseados em texto, em que os usuários precisavam inserir caracteres de uma imagem em um campo designado ou responder a perguntas simples. Com o tempo, os sistemas de verificação de usuários e os mecanismos de proteção de sites se tornaram mais sofisticados para combater os programas automatizados. Por outro lado, os desenvolvedores se esforçam para minimizar qualquer inconveniente para os usuários reais, permitindo que o processo de verificação ocorra em segundo plano sem o envolvimento do usuário.
Atualmente, a verificação não se baseia apenas na aprovação em um teste específico, mas na análise de uma ampla gama de fatores: comportamento do usuário, características do navegador, solicitações de rede e muito mais. Os sites podem inspecionar cookies, impressões digitais de dispositivos, execução de JavaScript e exibir um CAPTCHA somente quando for detectada atividade suspeita.
Outra camada de proteção é adicionada pelos chamados parâmetros dinâmicos. Esses parâmetros são criados e atualizados a cada solicitação ao CAPTCHA. Eles servem como identificadores exclusivos para cada sessão de verificação e, ao contrário dos parâmetros estáticos (como websitekey), que permanecem constantes, os parâmetros dinâmicos mudam a cada solicitação de CAPTCHA. Isso significa que um sistema automatizado não pode simplesmente reutilizar valores obtidos anteriormente para passar com êxito na verificação.
Sempre que um usuário solicita um CAPTCHA, o servidor gera um novo conjunto de dados (por exemplo, Esses parâmetros impedem a reutilização de respostas e podem incluir informações sobre o usuário, a sessão ou registros de data e hora. Mesmo que um bot consiga resolver um CAPTCHA, repetir o mesmo processo com diferentes parâmetros dinâmicos torna-se um desafio e exige recursos computacionais significativos.
Ao analisar dados comportamentais e de sessão, o site pode identificar a atividade do bot e bloquear temporariamente dispositivos suspeitos, mesmo sem emitir um CAPTCHA.
Essas medidas garantem que somente usuários reais possam passar pela "catraca", enquanto os bots são bloqueados ou enfrentam obstáculos significativos para resolver a proteção.
As alterações nos parâmetros do captcha variam de acordo com a solução e, em geral, com o fornecedor e o sistema de proteção usados. Eles são gerados durante a sessão ou após a conclusão da mesma. Vamos dar uma olhada em seus principais tipos importantes:
- Um desafio é, na verdade, o próprio elemento captcha, que o usuário deve resolver para confirmar sua identidade. Ele pode assumir uma variedade de formas, incluindo tarefas baseadas em texto, seleção de imagens ou execução de determinadas ações. Um desafio é criado pelo servidor quando a página é carregada e é um desafio exclusivo para cada solicitação. O usuário resolve o desafio e, depois disso, o servidor verifica a resposta e, se estiver correta, permite que o usuário continue interagindo com o site.
- Token é usado para verificar a sessão do usuário e confirmar que a solicitação vem de um usuário real e não de um bot. Os tokens podem ser criados no lado do servidor e transferidos para o cliente para uso no processo de captcha. O token geralmente é gerado no início da sessão ou em cada solicitação de captcha e, depois de passar com êxito pelo captcha, é enviado de volta ao servidor para verificação.
Além do desafio e do token, há parâmetros adicionais que podem ser específicos para diferentes tipos de captcha. Aqui estão alguns deles:
- context (usado, por exemplo, no AWS WAF) - contém valores exclusivos vinculados à sessão atual do usuário. Gerado no window.gokuProps:
window.gokuProps = {
"key":"",
"iv":"",
"context":""
};
- geetest_challenge ou desafio (usado em GeeTest v.3) é um identificador de captcha que vincula a solicitação de um usuário a uma sessão de verificação específica. Ele é gerado em um URL parecido com este (observe que esse link contém um registro de data e hora para evitar que a solicitação seja armazenada em cache):
https://example.com/api/v1/gee-test/init-params?t=1730640766594
O Geetest v.3 também usa os seguintes parâmetros:
- geetest_validate - código que confirma que o captcha foi resolvido corretamente. Gerado depois que um captcha bem-sucedido foi resolvido e confirma que a verificação foi aprovada;
- geetest_seccode - Um código de segurança adicional que confirma uma solução bem-sucedida.
- dataDomeCookie (usado em DataDome) - cookies gerados pelo sistema DataDome para rastrear e verificar o usuário quanto a ações automatizadas e atualizados em resposta ao seu comportamento.
- g-recaptcha-response (usado em ReCAPTCHA) - o token recebido após a aprovação do captcha é necessário para a transferência posterior para o servidor.
- cf_clearance (usado em Cloudflare checks) - cookies que são gerados após a aprovação do captcha para o acesso bem-sucedido ao recurso.
Também vale a pena mencionar parâmetros como:
- s (ou sentinel/motionData) - pode conter dados sobre os movimentos do mouse e a interação com o captcha..
- v (version) - Especifica a versão do captcha que pode ser atualizada no servidor e requer um valor atualizado para cada sessão.
- rqdata - contém dados criptografados da sessão do usuário.
Os exemplos dados refletem apenas uma parte dos parâmetros que mudam a cada sessão; na verdade, há muitos deles e, para cada tipo de verificação (captcha), eles são diferentes. Conhecer a presença deles é importante para a análise subsequente e a solução bem-sucedida do captcha.
Encontrar parâmetros dinâmicos, trabalhar com ferramentas de desenvolvedor
Se você usar serviços de solução de captcha, por exemplo, CapMonster Cloud, então, na documentação desses serviços, nas seções dedicadas aos tipos de captcha, geralmente são indicados quais parâmetros são dinâmicos e onde exatamente no código eles são gerados. Tudo isso é necessário para extrair os valores e, posteriormente, usá-los para resolver o captcha usando o serviço. Também é útil ter habilidades básicas de trabalho com as ferramentas de desenvolvedor para encontrar rapidamente os valores dos parâmetros necessários.
Primeiramente, vamos definir as principais maneiras de gerar esses parâmetros:
- Usando JavaScript (Client-side
Quando você abre uma página com um captcha, é carregado um script que rastreia suas ações - movimentos do mouse, cliques, pressionamentos de tecla. O JavaScript gera parâmetros - alguns elementos e formulários, janelas de validação intermediárias (como no caso do Cloudflare Challenge), números aleatórios, dados sobre suas interações e informações do dispositivo. Esses dados são então criptografados ou processados e enviados ao servidor.
- Usando a API (lado do servidor)
Ao processar uma solicitação de captcha, o servidor pode adicionar parâmetros úteis, como IDs de sessão ou valores com hash. A API também pode retornar parâmetros que serão necessários para criar uma nova sessão de captcha - eles são atualizados no servidor automaticamente para cada tentativa.
Para maior clareza, vamos considerar os dois métodos. Como exemplo, vamos pegar um captcha da Amazon com geração de contexto via JavaScript e o GeeTest v.3 com geração de chave de desafio via API
Amazon (AWS WAF)
Nesse tipo de captcha, parâmetros importantes (incluindo um contexto de alteração) são carregados por meio de um script especial de proteção do cliente:

Você pode encontrá-lo usando as Ferramentas do desenvolvedor entre os elementos na página de destino.
Aqui, os parâmetros do captcha são gerados por meio da API, você pode rastrear a URL necessária nas solicitações na guia Rede:

Um carimbo de data/hora também é gerado ali para que a solicitação seja vinculada a uma determinada hora.
Você pode determinar os parâmetros necessários analisando solicitações e respostas entre o navegador e o servidor. Aqui estão as principais maneiras e uma abordagem passo a passo:
- Ferramentas de desenvolvedor:
- Abra uma página da Web com um captcha;
- Vá para a guia "Rede";
- Encontre consultas relacionadas ao captcha (geralmente são solicitações aos servidores de captcha, por exemplo, api.geetest.com, etc.);
- Verifique os parâmetros passados nessas solicitações, por exemplo: ?t=123456789123;
- Compare várias consultas;
- Refresh a página várias vezes;
- Compare os parâmetros. Se os valores mudarem entre as solicitações, eles são dinâmicos;
- Encontrar chamadas JavaScript
- Procure no DevTools na guia "Fontes" ou "Elementos". Verifique quais scripts estão conectados;
- Encontre a geração de parâmetros, como registro de data e hora, contexto, desafio etc.;
- Procure palavras-chave: O código JavaScript geralmente usa funções para gerar parâmetros dinâmicos;
9. Analise as solicitações do servidor. Alguns parâmetros são gerados pelo servidor. Esses dados devem ser salvos e usados na próxima consulta. Se a sequência de solicitações estiver quebrada (por exemplo, cookies obsoletos), o servidor poderá rejeitar a verificação.
- Sniffers e servidores proxy para análise
Essas ferramentas, como o Charles Proxy, permitem interceptar solicitações, encontrar parâmetros dinâmicos e testar alterações, ajudam a entender sua lógica e verificar como o servidor lida com solicitações modificadas.
O trabalho dessas ferramentas inclui:
- As ferramentas registram solicitações para o servidor de captcha (por exemplo, com os parâmetros t, challenge, context).
- Os cabeçalhos, os parâmetros de URL, o corpo da solicitação e os cookies são examinados para identificar valores-chave.
- Altera os parâmetros (por exemplo, tokens) para verificar seu impacto na resposta do servidor.
- É testado como o servidor reage aos dados alterados.
Um guia rápido para usar o Charles Proxy para analisar os parâmetros do captcha:
- Baixe e instale o Charles Proxy.
- Habilite o proxy SSL por meio do proxy → Configurações de proxy SSL.... Adicione um domínio de captcha
- Inicie o Charles e o navegador com a página em que o captcha é carregado.
- Vá para a página para começar a registrar as solicitações.
- Na guia Estrutura, localize as solicitações para os serviços de CAPTCHA (por exemplo, www.google.com/recaptcha/api.js).
- Abra as solicitações/respostas e examine os parâmetros passados nelas (token, sitekey, desafio, cookies etc.).
Outra forma de analisar dados de captcha e, em combinação com outras ferramentas, automatizar sua solução, são os emuladores de navegador - por exemplo, Selenium, Puppeteer e Playwright.
Automatização. Todas as três ferramentas permitem gerenciar navegadores, executar ações comuns do usuário: cliques, entrada de texto, navegação na página etc. Tudo isso pode ser feito de forma automatizada
Suporte para trabalhar com conteúdo dinâmico. Selenium, Puppeteer e Playwright podem trabalhar com JavaScript, para que você possa lidar com elementos de página carregados dinamicamente.
Testes. Eles são amplamente usados para automatizar o teste de vários aplicativos da Web.
Python
# Importar as dependências necessárias
importar requests
import asyncio
import time
from capmonstercloudclient import CapMonsterClient, ClientOptions
from capmonstercloudclient.requests import GeetestProxylessRequest
async def run():
# Criando um cliente CapMonster Cloud
client_options = ClientOptions(api_key='your_api_key') # Substitua por sua chave de API CapMonsterCloud
cmc_client = CapMonsterClient(options=client_options)
# Obter parâmetros de captcha por meio da API
t = int(time.time() * 1000) # Obtenha o registro de data e hora atual em milissegundos
response = requests.get(f'https://example.com/api/v1/gee-test/init-params?t={t}')
dados = response.json()
challenge = data.get('challenge')
gt = dados.get('gt')
if not challenge or not gt:
raise ValueError('Failed to get parameters for captcha.')
# Criação de uma solicitação para resolver o captcha gee_test_proxyless_request = GeetestProxylessRequest(
websiteUrl='https://example.com', # URL da página com o captcha
gt=gt,
challenge=desafio
)
# Envio de uma solicitação para uma solução de captcha
solution_response = await cmc_client.solve_captcha(gee_test_proxyless_request)
if not solution_response or not solution_response:
raise ValueError('Captcha não resolvido.')
print('Captcha resolvido:', solution_response)
asyncio.run(run())
C#
/ Importar a biblioteca CapMonster Cloud e as dependências necessárias
using Zennolab.CapMonsterCloud.Requests;
using Zennolab.CapMonsterCloud;
using Newtonsoft.Json;
class Program
{
static async Task Main(string[] args)
{
// Configuração de um cliente com sua chave de API do CapMonster Cloud
var clientOptions = new ClientOptions
{
ClientKey = "your_api_key" // Substitua por sua chave de API do CapMonster Cloud
};
// Criação de um cliente do CapMonster Cloud usando as configurações especificadas var cmCloudClient = CapMonsterCloudClientFactory.Create(clientOptions);
// Criação de um cliente HTTP para enviar solicitações usando var httpClient = new HttpClient();
// Obter o registro de data e hora atual para a solicitação
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
// Formando um URL para obter parâmetros dinâmicos do captcha do GeeTest
var requestUrl = $"https://example.com/api/v1/captcha/gee-test/init-params?t={timestamp}";
// Enviar uma solicitação e obter uma resposta na forma de uma cadeia de caracteres
var response = await httpClient.GetStringAsync(requestUrl);
dados dinâmicos = JsonConvert.DeserializeObject(response);
// Criação de uma consulta para resolver o captcha do GeeTest com os parâmetros obtidos
var geetestRequest = new GeeTestProxylessRequest
{
WebsiteUrl = "https://example.com/demo/geetest", // URL da página com o captcha Gt = data.gt, // O parâmetro gt derivado da resposta
Challenge = data.challenge // O parâmetro de desafio derivado da resposta
};
// Envio de uma solicitação para resolver um captcha e obtenção do resultado
var geetestResult = await cmCloudClient.SolveAsync(geetestRequest);
Console.WriteLine($"Captcha Solution:\nChallenge: {geetestResult.Solution.Challenge}\nValidate: {geetestResult.Solution.Validate}\nSecCode: {geetestResult.Solution.SecCode}");
}
}
Para trabalhar com esse tipo de verificação, você precisa usar emuladores de navegador para exibir corretamente o conteúdo dinâmico e abrir uma janela especial para verificar a página de desafio. Os parâmetros dinâmicos são gerados via window.turnstile, e nós os interceptaremos usando JavaScript incorporado. Esses parâmetros são usados para formar uma solicitação para o servidor CapMonster Cloud. Vamos considerar duas maneiras: obter um token e um cookie cf-clearance, que podem ser inseridos no navegador, confirmando assim uma decisão bem-sucedida. Uma lista de todos os parâmetros necessários está listada no CapMonster Cloud documentação.
JavaScript
// Importar a biblioteca CapMonster Cloud
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const { CapMonsterCloudClientFactory, ClientOptions, TurnstileRequest } = require('@zennolab_com/capmonstercloud-client');
(função assíncrona example() {
// Criar um objeto de configurações para o Chrome
const options = new chrome.Options();
// Criação e execução de um driver para o navegador Chrome
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options) // Definindo as configurações para o Chrome
.build();
let params = null; // Variável para armazenar parâmetros de captcha
try {
while (!params) {
// Abrir uma página com um captcha
await driver.get('https://example.com'); // URL da página com o captcha
// Executando JavaScript na página para capturar os parâmetros do captcha
await driver.executeScript(`
// Interceptando uma chamada para a função de renderização em um objeto de catraca para obter parâmetros
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === 'render') {
// Substituindo a função de renderização para capturar os parâmetros do captcha
return function(a, b) {
let p = {
websiteKey: b.sitekey, // Chave do site
websiteURL: window.location.href, // URL da página com o captcha
data: b.cData,
pagedata: b.chlPageData,
action: b.action,
userAgent: navigator.userAgent
};
console.log(JSON.stringify(p)); // Saída dos parâmetros para o console para depuração
window.params = p; // Salvar parâmetros em uma variável global
window.turnstileCallback = b.callback; // Salva a função de retorno de chamada
return target.render.apply(this, arguments); // Chamando a função de renderização original
}
}
return target[prop]; // Retorna o restante das propriedades do objeto
}
});
`);
// Obtenção de parâmetros da variável global window.params
params = await driver.executeAsyncScript(`
const callback = arguments[arguments.length - 1]; // Obter um retorno de chamada para concluir
setTimeout(() => {
callback(window.params); // Passagem de parâmetros via callback
}, 5000);
`);
Se (!params) {
console.log('Os parâmetros não foram recebidos, recarregue a página...');
await driver.sleep(3000);
}
}
console.log('Options:', params); // Exibindo os parâmetros obtidos
// Criação de um cliente CapMonster Cloud usando uma chave de API
const cmcClient = CapMonsterCloudClientFactory.Create(new ClientOptions({
clientKey: 'your_api_key', // Substitua por sua chave de API do CapMonster Cloud
}));
// Criação de uma solicitação para resolver o captcha da catraca com os parâmetros recebidos
const turnstileRequest = new TurnstileRequest({
websiteURL: params.websiteURL,
websiteKey: params.websiteKey,
data: params.data,
action: params.action,
cloudflareTaskType: 'token',
pageAction: 'managed',
pageData: params.pagedata
});
// Envio de uma solicitação para uma solução de captcha
const response = await cmcClient.Solve(turnstileRequest);
// Verificar se o captcha foi resolvido
Se (!response || !response.solution) {
lançará um novo erro ('Captcha não resolvido');
}
console.log('Captcha resolvido:', response.solution); // Exibindo a solução do captcha
// Execução de JavaScript na página para passar o token recebido para a função de retorno de chamadaю
await driver.executeScript(`
window.turnstileCallback('${response.solution.token}'); // Passando o token da solução do captcha para a função de retorno de chamada
`);
} catch (err) {
console.error('Error:', err);
} finally {
await driver.quit();
}
})();
Python
# Importar as dependências necessárias
import 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
# Configuração do CapMonsterCloud usando uma chave de API
client_options = ClientOptions(api_key="your_api_key") # Substitua por sua chave de API do CapMonsterCloud
cap_monster_client = CapMonsterClient(options=client_options)
# Função para obter parâmetros de captcha
async def get_turnstile_params(driver):
params = None # Variável para armazenar parâmetros de captcha
while not params:
driver.get("https://example.com") # Abre uma página da Web com um captcha
# Execute o código JavaScript para interceptar a função de renderização e extrair os parâmetros
driver.execute_script("""
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === 'render') {
// Substituindo a função render para capturar os parâmetros do captcha
return function(a, b) {
let p = {
websiteKey: b.sitekey, // Chave do site
websiteURL: window.location.href, // URL da página com o captcha
data: b.cData,
pagedata: b.chlPageData,
action: b.action,
userAgent: navigator.userAgent
};
console.log(JSON.stringify(p));
window.params = p; // Salvando parâmetros em uma variável global
window.turnstileCallback = b.callback; // Salvando a função de retorno de chamada
return target.render.apply(this, arguments); // Chama a função original render
};
}
return target[prop]; // Retorna o restante das propriedades do objeto
}
});
""")
# Extração de parâmetros de uma variável global `window.params` por meio de execute_async_script
params = driver.execute_async_script("""
const callback = arguments[arguments.length - 1]; // Obter um retorno de chamada para concluir
setTimeout(() => {
callback(window.params); // Passagem de parâmetros via callback
}, 5000);
""")
if not params:
print("Os parâmetros não foram recebidos, recarregue a página...")
await asyncio.sleep(3)
return params # Retorna os parâmetros recebidos
async def solve_turnstile(params):
# Criar uma solicitação para resolver um captcha usando o CapMonsterCloud
request = TurnstileProxylessRequest(
websiteURL=params["websiteURL"],
websiteKey=parâmetros["websiteKey"],
data=params["data"],
action=params["action"],
pageAction="managed" (gerenciado),
cloudflareTaskType="token",
pageData=params["pagedata"],
userAgent=params["userAgent"]
)
# Enviar uma solicitação para resolver o captcha e obter um token
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:
# Obter os parâmetros do captcha
params = await get_turnstile_params(driver)
print("Parâmetros recebidos:", params)
# Resolver o captcha e obter um token
token = await solve_turnstile(params)
print("Captcha resolvido. Token:", token)
# Execute o JavaScript para passar o token para a função de retorno de chamada
driver.execute_script(f "window.turnstileCallback('{token}');")
except Exception as e:
# Tratamos os erros se eles ocorrerem
print(f "Erro: {e}")
finally:
await asyncio.sleep(5)
driver.quit()
asyncio.run(main())
C#
// Importando as dependências necessárias
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using Zennolab.CapMonsterCloud;
usando Zennolab.CapMonsterCloud.Requests;
class Program
{
static async Task Main(string[] args)
{
// Configurações do CapMonster Cloud usando a chave da API
var clientOptions = new ClientOptions
{
ClientKey = "your_api_key" // Substitua por sua chave de API do CapMonster Cloud
};
// Criação de um cliente para trabalhar com o CapMonster Cloud
var cmCloudClient = CapMonsterCloudClientFactory.Create(clientOptions);
// Configurações do ChromeDriver
var chromeOptions = new ChromeOptions();
// Inicialização do driver do Chrome
using var driver = new ChromeDriver(chromeOptions);
// Obtenção de parâmetros de captcha
var paramsObtained = await GetTurnstileParams(driver);
Console.WriteLine("Parâmetros recebidos: " + string.Join(", ", paramsObtained));
// Criação de uma solicitação de solução de captcha
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()
};
// Solução de Captcha usando o CapMonster Cloud
var turnstileResult = await cmCloudClient.SolveAsync(turnstileRequest);
Console.WriteLine("Captcha resolvido. Token: " + turnstileResult.Solution.Value);
// Passar o token para a função de retorno de chamada na página
((IJavaScriptExecutor)driver).ExecuteScript($"window.turnstileCallback('{turnstileResult.Solution.Value}');");
await Task.Delay(5000);
}
// Função para obter parâmetros de captcha
static async Task<Dictionary<string, object>> GetTurnstileParams(IWebDriver driver)
{
Dictionary<string, object> paramsObtained = null; // Variável para armazenar parâmetros
while (paramsObtained == null) // Repetir até que os parâmetros sejam obtidos
{
driver.Navigate().GoToUrl("https://example.com"); // Abra a página com o captcha
// Executando JavaScript para interceptar os parâmetros do captcha
((IJavaScriptExecutor)driver).ExecuteScript(@"
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === 'render') {
// Substituindo a função render para extrair parâmetros
return function(a, b) {
let 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; // Salvando parâmetros em uma variável global
window.turnstileCallback = b.callback; // Salvando a função de retorno de chamada
return target.render.apply(this, arguments); // Chamando a função de renderização original
};
}
return target[prop]; // Retorna o restante das propriedades do objeto
}
});
");
// Extrair os parâmetros da variável global 'window.params' por meio do ExecuteAsyncScript
paramsObtained = await Task.Run(() =>
{
return (Dictionary<string, object>)((IJavaScriptExecutor)driver).ExecuteAsyncScript(@"
const callback = arguments[arguments.length - 1]; // Callback para concluir a execução
setTimeout(() => {
callback(window.params); // Passagem de parâmetros via callback
}, 5000);
");
});
// Se os parâmetros não forem obtidos, aguarde antes de tentar novamente
Se (paramsObtained == null)
{
Console.WriteLine("Os parâmetros não foram recebidos, recarregue a página...");
await Task.Delay(3000);
}
}
return paramsObtained; // Retorna os parâmetros recebidos
}
}
JavaScript
// Importando as dependências necessárias
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const { CapMonsterCloudClientFactory, ClientOptions, TurnstileRequest } = require('@zennolab_com/capmonstercloud-client');
(função assíncrona example() {
// Configurações do ChromeDriver
const options = new chrome.Options();
// Inicialização do WebDriver para sChrome
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
let params = null; // Variável para armazenar os parâmetros do captcha
let htmlPageBase64 = ''; // Variável para armazenar a página no formato Base64
try {
while (!params) {
// Abrir a página com o captcha
await driver.get('https://example.com'); // Substitua pelo URL da sua página
// Executar um script para interceptar os parâmetros do captcha do Turnstile
await driver.executeScript(`
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === 'render') {
// Substituindo a função render para extrair parâmetros
return function(a, b) {
let p = {
websiteKey: b.sitekey,
websiteURL: window.location.href
};
console.log(JSON.stringify(p));
window.params = p; // Salvando parâmetros em uma variável global
return target.render.apply(this, arguments); //Chamando a função de renderização original }
}
return target[prop]; // Retorna o restante das propriedades do objeto
}
});
`);
// Extrair os parâmetros usando a variável global 'window.params'
params = await driver.executeAsyncScript(`
const callback = arguments[arguments.length - 1];
setTimeout(() => {
callback(window.params); // Retorna parâmetros via callback
}, 5000);
`);
Se (!params) {
console.log('Os parâmetros não foram recebidos, recarregue a página...');
await driver.sleep(3000); }
}
console.log('Parâmetros do Captcha:', params);
// Obter o código HTML da página e codificá-lo em Base64
const pageSource = await driver.getPageSource();
htmlPageBase64 = Buffer.from(pageSource).toString('base64');
// Provisionamento do cliente do CapMonster Cloud
const cmcClient = CapMonsterCloudClientFactory.Create(new ClientOptions({
clientKey: 'your_api_key', // Substitua por sua chave de API do CapMonster Cloud
}));
// Formando uma solicitação para resolver o captcha
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, como Gecko) Chrome/131.0.0.0 Safari/537.36',
htmlPageBase64: htmlPageBase64,
proxyType: 'http',
proxyAddress: '8.8.8.8',
proxyPort: 8000,
proxyLogin: 'proxyLoginHere',
proxyPassword: 'proxyPasswordHere'
});
// Solução de Captcha usando o CapMonster Cloud
const response = await cmcClient.Solve(turnstileRequest);
se (!response || !response.solution) {
lançará um novo erro ('Captcha não resolvido');
}
console.log('Captcha resolvido, cookie cf_clearance:', response.solution);
} catch (err) {
console.error('Error:', err);
} finally {
await driver.quit();
}
})();
Python
# Importar as dependências necessárias
import asyncio
import 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
# Configuração do cliente do CapMonster Cloud
client_options = ClientOptions(api_key="your_api_key") # Substitua por sua chave de API do CapMonsterCloud
cap_monster_client = CapMonsterClient(options=client_options)
# Função para obter os parâmetros do Turnstile
async def get_turnstile_params(driver):
params = None
while not params:
# Carregando a página com o captcha
driver.get("https://example.com") # Especifica o URL da página com o captcha
# Execute um script para interceptar os parâmetros do Turnstile
driver.execute_script("""
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === 'render') {
// Sobrepondo o método render para extrair parâmetros
return function(a, b) {
let p = {
websiteKey: b.sitekey,
websiteURL: window.location.href
};
console.log(JSON.stringify(p));
window.params = p; // Salvando parâmetros em uma variável global
return target.render.apply(this, arguments);
};
}
return target[prop]; // Retorna o restante das propriedades do objeto
}
});
""")
# Extração de parâmetros usando um script assíncrono
params = driver.execute_async_script("""
const callback = arguments[arguments.length - 1];
setTimeout(() => {
callback(window.params || null); // Retorna parâmetros ou nulo
}, 5000);
""")
if not params:
print("Os parâmetros não foram recebidos, recarregue a página...")
await asyncio.sleep(3) # Aguardando antes de tentar novamente
return params
# Função para resolver captchas
async def solve_turnstile(params, html_page_base64):
request = TurnstileRequest(
websiteURL=params["websiteURL"],
websiteKey=parâmetros["websiteKey"],
cloudflareTaskType="cf_clearance",
userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, como 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"
)
# Envio de uma solicitação para uma solução de captcha
response = await cap_monster_client.solve_captcha(request)
print("Resposta do CapMonster:", resposta)
se "cf_clearance" não estiver na resposta:
raise Exception("Captcha não resolvido.")
return response["cf_clearance"]
async def main():
chrome_options = Options()
driver = webdriver.Chrome(service=ChromeService(), options=chrome_options)
try:
# Obter os parâmetros do Turnstile
params = await get_turnstile_params(driver)
print("Parâmetros do Captcha recebidos", params)
# Codificação de páginas HTML em Base64
page_source = driver.page_source
html_page_base64 = base64.b64encode(page_source.encode("utf-8")).decode("utf-8")
print("O HTML da página está codificado em Base64.")
# Resolvendo o captcha
cf_clearance = await solve_turnstile(params, html_page_base64)
print("Captcha resolvido. Cookie cf_clearance:", cf_clearance)
exceto Exception as e:
print(f "Error: {e}")
finally:
await asyncio.sleep(5)
driver.quit()
asyncio.run(main())
C#
// Importando as dependências necessárias
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using Zennolab.CapMonsterCloud;
usando Zennolab.CapMonsterCloud.Requests;
class Program
{
static async Task Main(string[] args)
{
// Configurações do cliente CapMonster Cloud
var clientOptions = new ClientOptions
{
ClientKey = "your_api_key" // Substitua por sua chave de API do CapMonsterCloud
};
var cmCloudClient = CapMonsterCloudClientFactory.Create(clientOptions);
// Configuração do ChromeDriver
var chromeOptions = new ChromeOptions();
usando var driver = new ChromeDriver(chromeOptions);
try
{
// Obtenção de parâmetros da catraca
var paramsObtained = await GetTurnstileParams(driver);
Console.WriteLine("Parâmetros recebidos: " + string.Join(", ", paramsObtained));
// Criação de uma solicitação para resolver um captcha
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",
ProxyPort = 8000,
ProxyLogin = "proxyLoginHere",
ProxyPassword = "proxyPasswordHere",
PageData = paramsObtained["pagedata"].ToString(),
Data = paramsObtained["data"].ToString(),
HtmlPageBase64 = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(driver.PageSource)), // Codificação de uma página HTML
UserAgent = paramsObtained["userAgent"].ToString()
};
// envio de uma solicitação para o CapMonster Cloud
var turnstileResult = await cmCloudClient.SolveAsync(turnstileRequest);
Console.WriteLine("Captcha resolvido. Cookie cf_clearance: " + turnstileResult.Solution.Clearance);
// Se necessário, adicione cf_clearance aos cookies do navegador
// var cfClearance = turnstileResult.Solution.Clearance;
// driver.Manage().Cookies.AddCookie(new Cookie("cf_clearance", cfClearance));
// Se você precisar de um retorno de chamada, faça-o por meio de JavaScript
// ((IJavaScriptExecutor)driver).ExecuteScript($"window.turnstileCallback('{cfClearance}');");
}
catch (Exception ex)
{
Console.WriteLine("Erro: " + ex.Message);
}
finally
{
await Task.Delay(5000);
driver.Quit();
}
}
// Função para obter os parâmetros da catraca
static async Task<Dictionary<string, object>> GetTurnstileParams(IWebDriver driver)
{
Dictionary<string, object> paramsObtained = null;
while (paramsObtained == null)
{
// Abrir a página da catraca
driver.Navigate().GoToUrl("https://example.com"); // Especificar um URL com um captcha
// Substituir o método de renderização por JavaScript
((IJavaScriptExecutor)driver).ExecuteScript(@"
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
se (prop === 'render') {
return function(a, b) {
let 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; // Salve a chamada de retorno para uma chamada subsequente
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); // Retorna os parâmetros se eles existirem
}, 5000);
");
});
Se (paramsObtained == null)
{
Console.WriteLine("Parâmetros não recebidos, recarga da página...");
await Task.Delay(3000);
}
}
return paramsObtained;
}
}
JavaScript
// Importando as dependências necessárias
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const { CapMonsterCloudClientFactory, ClientOptions, AmazonProxylessRequest } = require('@zennolab_com/capmonstercloud-client');
(função assíncrona run() {
// Configurações para o Chrome
const options = new chrome.Options();
// options.addArguments('--headless'); // Adicione se você quiser executar em segundo plano
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
const pageUrl = 'https://example.com'; // Forneça o URL da página com o CAPTCHA
await driver.get(pageUrl);
// Obter parâmetros do captcha usando JavaScript
const captchaParams = await driver.executeScript(() => {
const gokuProps = window.gokuProps || {}; // Obtém o objeto gokuProps se ele existir
const scripts = Array.from(document.querySelectorAll('script')); // Coleta todas as tags <script>
return {
websiteKey: gokuProps.key || "Não encontrado",
context: gokuProps.context || "Não encontrado",
iv: gokuProps.iv || "Não encontrado",
challengeScriptUrl: scripts.find(script => script.src.includes('challenge.js'))?.src || "Não encontrado",
captchaScriptUrl: scripts.find(script => script.src.includes('captcha.js'))?.src || "Não encontrado"
};
});
console.log('Parâmetros obtidos:', captchaParams);
// Configuração do cliente do CapMonster Cloud
const cmcClient = CapMonsterCloudClientFactory.Create(new ClientOptions({
clientKey: 'your_api_key', // Substitua por sua chave de API
}));
// Criação de uma solicitação de solução de captcha
const amazonProxylessRequest = new AmazonProxylessRequest({
websiteURL: pageUrl,
challengeScript: captchaParams.challengeScriptUrl,
captchaScript: captchaParams.captchaScriptUrl,
websiteKey: captchaParams.websiteKey,
context: captchaParams.context,
iv: captchaParams.iv,
cookieSolution: false, // Se você quiser receber um cookie, defina-o como true
});
try {
// Solução de Captcha via CapMonster Cloud
const response = await cmcClient.Solve(amazonProxylessRequest);
se (!response?.solution) lançar um novo erro('CAPTCHA não resolvido.');
console.log('CAPTCHA resolvido:', response.solution);
} catch (err) {
console.error('Erro na solução do CAPTCHA:', err);
} finally {
await driver.quit();
}
})()
.then(() => {
console.log('DONE');
process.exit(0);
})
.catch(err => {
console.error('ERRO:', err);
process.exit(1);
});
Python
# Importar dependências necessárias
import 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" # Digite o URL que você deseja
# Configuração do ChromeDriver
chrome_options = Options()
# chrome_options.add_argument('--headless') # Remover comentários para trabalho em segundo plano
driver = webdriver.Chrome(options=chrome_options)
def get_captcha_params():
"""
Obter os parâmetros do CAPTCHA da página via JavaScript.
"""
driver.get(CAPTCHA_URL)
captcha_params = driver.execute_script("""
const gokuProps = window.gokuProps || {}; // Obter gokuProps com o
const scripts = Array.from(document.querySelectorAll('script')); // Tudo na página
return {
websiteKey: gokuProps.key || "Não encontrado",
context: gokuProps.context || "Não encontrado",
iv: gokuProps.iv || "Não encontrado",
challengeScriptUrl: scripts.find(script => script.src.includes('challenge.js'))?.src || "Não encontrado",
captchaScriptUrl: scripts.find(script => script.src.includes('captcha.js'))?.src || "Não encontrado"
};
""")
retornar captcha_params
# Configurações do CapMonsterCloud
client_options = ClientOptions(api_key="your_api_key") # Substitua por sua chave de API
cap_monster_client = CapMonsterClient(options=client_options)
async def solve_captcha(captcha_params):
"""
Crie uma solicitação para o CapMonsterCloud e envie-a para resolver o captcha.
"""
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 # Se for necessária uma solução de cookie, especifique True
)
return await cap_monster_client.solve_captcha(amazon_waf_request)
async def main():
try:
# Extração dos parâmetros do captcha
captcha_params = get_captcha_params()
print("Opções CAPTCHA:", captcha_params)
# Solução do Captcha
response = await solve_captcha(captcha_params)
print("Resultado da solução CAPTCHA:", response)
exceto Exception as e:
print("Ocorreu um erro:", e)
finalmente:
driver.quit()
asyncio.run(main())
C#
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using Zennolab.CapMonsterCloud;
using Zennolab.CapMonsterCloud.Requests;
classe Programa
{
static async Task Main(string[] args)
{
const string CAPTCHA_URL = "https://example.com"; // URL com CAPTCHA
// Configurações do ChromeDriver
var chromeOptions = new ChromeOptions();
// chromeOptions.AddArgument("--headless"); // Remover comentários para trabalho em segundo plano
usando var driver = new ChromeDriver(chromeOptions);
// Extração dos parâmetros do captcha
var captchaParams = GetCaptchaParams(driver, CAPTCHA_URL);
// Configurações do CapMonster Cloud
var clientOptions = new ClientOptions
{
ClientKey = "your_api_key" // Substitua por sua chave de API do CapMonster Cloud
};
var cmCloudClient = CapMonsterCloudClientFactory.Create(clientOptions);
// Criação de uma solicitação
var amazonWafRequest = new AmazonWafProxylessRequest
{
WebsiteUrl = CAPTCHA_URL,
ChallengeScript = captchaParams["challengeScriptUrl"],
CaptchaScript = captchaParams["captchaScriptUrl"],
WebsiteKey = captchaParams["websiteKey"],
Context = captchaParams["context"],
Iv = captchaParams["iv"],
CookieSolution = false
};
// Enviar uma solicitação de solução
var solveResult = await cmCloudClient.SolveAsync(amazonWafRequest);
// Saída dos resultados
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;
// Execução de JavaScript para extrair parâmetros var captchaParams = jsExecutor.ExecuteScript(@"
const gokuProps = window.gokuProps || {};
const scripts = Array.from(document.querySelectorAll('script'));
return {
websiteKey: gokuProps.key || 'Não encontrado',
context: gokuProps.context || 'Não encontrado',
iv: gokuProps.iv || 'Não encontrado',
challengeScriptUrl: scripts.find(script => script.src.includes('challenge.js'))?.src || 'Não encontrado',
captchaScriptUrl: scripts.find(script => script.src.includes('captcha.js'))?.src || 'Não encontrado'
};
") como IDictionary<string, object>;
return captchaParams.ToDictionary(k => k.Key, v => v.Value?.ToString() ?? "Não encontrado");
}
}
Trabalhar com parâmetros dinâmicos e solução automática de captcha geralmente traz complicações, como blocos, captchas ou elementos de página atualizados dinamicamente. Abaixo estão dicas práticas para resolver essas restrições com sucesso.
- Use o ChromeDriver não detectado
Os identificadores padrão do Selenium WebDriver são facilmente detectados pelos sistemas de segurança. Para minimizar a probabilidade de bloqueio:
Instale a biblioteca undetected_chromedriver. Ela mascara automaticamente o uso do WebDriver:
pip install undetected-chromedriver
Exemplo de uso:
import undetected_chromedriver.v2 as uc
options = uc.ChromeOptions()
options.add_argument("--headless") # Executar em segundo plano
options.add_argument("--disable-blink-features=AutomationControlled")
driver = uc.Chrome(options=options)
driver.get("https://example.com")
print(driver.page_source)
driver.quit()
Ative o modo de navegador sem cabeça para reduzir ainda mais as suspeitas.
2. Emulação de ações do usuário
Um script muito "robótico" pode levantar suspeitas. Use as seguintes técnicas:
- Atraso dinâmico: Insira intervalos de atraso aleatórios entre as ações:
import time
import random
time.sleep(random.uniform(1, 3)) # Atraso de 1 a 3 segundos
- Rrolagem da página. A emulação de rolagem faz com que o script se pareça com um usuário:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
Movimento do mouse: Simule ações do mouse com bibliotecas como pyautogui ou selenium-wire
3. Usando servidores proxy
Os proxies ajudam a evitar o bloqueio por endereço IP:
Use a rotação de proxy. Fique de olho na geografia do proxy para corresponder à região do site:
from selenium.webdriver.common.proxy import Proxy, ProxyType
proxy = Proxy()
proxy.proxy_type = ProxyType.MANUAL
proxy.http_proxy = "http://username:password@proxy_ip:port"
capacidades = webdriver.DesiredCapabilities.CHROME
proxy.add_to_capabilities(capabilities)
driver = webdriver.Chrome(desired_capabilities=capabilities)
4. Atualizar o agente do usuário e os cabeçalhos
options.add_argument("user-agent=Your User-Agent")
Então, dicas para trabalho de longo prazo sem bloqueio:
- Evite a raspagem agressiva.
- Use bibliotecas que mudam o comportamento para se diferenciar de outros scripts.
- Use o modo sem cabeça com cuidado: Alguns sites reconhecem um navegador "sem cabeça".
Trabalhar com parâmetros de captcha dinâmicos é um processo empolgante que permite que você entenda melhor como funcionam os mecanismos de proteção da Web. Neste artigo, analisamos os principais pontos em detalhes: desde como identificar e analisar parâmetros dinâmicos até como extraí-los e solucionar captchas de forma eficaz.
Também mostramos exemplos de código em várias linguagens de programação para que você possa aprender facilmente como extrair os valores desejados e automatizar a solução de captchas com o CapMonster Cloud.
Não nos esquecemos das ferramentas que o ajudarão a emular as ações do usuário e a trabalhar com servidores proxy. O uso de soluções como Selenium, Puppeteer, Playwright, Undetected ChromeDriver, proxies de alta qualidade, rotação de User-Agent e emulação do comportamento do usuário lhe dará a oportunidade de resolver muitas limitações.
Ao mesmo tempo, é importante lembrar a frequência das solicitações e seguir as regras de uso de recursos da Web para que sua automação não seja apenas eficaz, mas também ética. Boa sorte na implementação de suas ideias e novos projetos!
Nota: Gostaríamos de lembrá-lo de que o produto é usado para automatizar testes em seus próprios sites e em sites aos quais você tem acesso legal.