Neste artigo, procuramos responder a todas as principais dúvidas. Para começar a resolver o problema, o primeiro passo é identificar qual sistema de proteção está sendo utilizado. Para isso, você pode consultar a lista de captchas e sistemas de proteção antibot mais populares, onde há exemplos visuais e sinais principais que ajudam a identificar rapidamente com o que você está lidando.
Se você notar que o seu site utiliza TenDI (Tencent), o passo seguinte é estudar com mais detalhes as suas características e o seu funcionamento. Neste mesmo artigo, você também pode conferir o guia de integração do TenDI (Tencent), para entender por completo como o sistema opera no seu site. Isso permitirá não apenas compreender a proteção atual, mas também planejar adequadamente a sua manutenção.
Trabalhar com o CapMonster Cloud via API normalmente envolve as etapas abaixo:
type - CustomTask
class - TenDI
websiteURL - Endereço da página onde o captcha será resolvido.
websiteKey - captchaAppId. Exemplo: "websiteKey": "189123456" — parâmetro único para seu site
captchaUrl (dentro do metadata) - Link para o script do captcha. Normalmente termina em TCaptcha.js ou TCaptcha-global.js;
websiteURL - Endereço da página onde o captcha será resolvido;
userAgent (opcional) - User-Agent do navegador. Envie apenas o UA atual do Windows.
Você receberá dois parâmetros: CaptchaAppId e AppSecretKey. Eles serão usados no frontend e no servidor.
Ao clicar, o captcha aparece e, após resolução, o resultado é exibido no console.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Captcha Example</title>
// Carregamento obrigatório do JS do captcha
<script src="https://ca.turing.captcha.qcloud.com/TJNCaptcha-global.js"></script>
</head>
<body>
<div id="cap_iframe"></div>
<button id="CaptchaId">Verification</button>
<script>
// Processamento do resultado
function callback(res) {
console.log("callback:", res);
if (res.ret === 0) {
// Verificação bem-sucedida
const text = `[randstr] ${res.randstr} | [ticket] ${res.ticket}`;
const input = document.createElement("input");
input.value = text;
document.body.appendChild(input);
input.select();
document.execCommand("Copy");
document.body.removeChild(input);
alert("Ticket e randstr copiados para a área de transferência.");
}
}
// Tratamento de erros ao carregar o script do captcha
function loadErrorCallback() {
const appid = "CaptchaAppId";
const ticket = `trerror_1001_${appid}_1780975384`;
callback({
ret: 0,
randstr: "@" + Math.random().toString(36).slice(2),
ticket,
errorCode: 1001,
errorMessage: "jsload_error",
});
}
window.onload = function () {
document.getElementById("CaptchaId").onclick = function () {
try {
const captcha = new TencentCaptcha(
document.getElementById("cap_iframe"),
"Your CaptchaAppId",
callback,
{}
);
captcha.show();
} catch (e) {
loadErrorCallback();
}
};
};
</script>
</body>
</html>
Se você herdou um site que já tem um captcha ou outro sistema de proteção instalado e não tem acesso ao código, não tem problema! É bem fácil identificar qual tecnologia está sendo usada. Para verificar se tudo está funcionando corretamente, você pode usar o serviço de reconhecimento CapMonster Cloud em um ambiente de testes isolado, para garantir que o mecanismo de processamento de tokens e a lógica de verificação estejam funcionando corretamente.
No caso de TenDI (Tencent), basta identificar o sistema, analisar o comportamento dele e se certificar de que a proteção está funcionando corretamente. No artigo, mostramos como identificar TenDI (Tencent) e onde encontrar instruções para a integração ou reconfiguração, para que você consiga manter a proteção com segurança e controlar o funcionamento dela.
https://api.capmonster.cloud/createTask
{
"clientKey": "API_KEY",
"task": {
"type": "CustomTask",
"class": "TenDI",
"websiteURL": "https://example.com",
"websiteKey": "189123456",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36",
"metadata": {
"captchaUrl": "https://global.captcha.example.com/TCaptcha-global.js"
}
}
}
{
"errorId":0,
"taskId":407533072
}https://api.capmonster.cloud/getTaskResult{
"clientKey":"API_KEY",
"taskId": 407533072
}
{
"errorId":0,
"status":"ready",
"solution": {
"data": {
"randstr": "@EcL",
"ticket": "tr03lHUhdnuW3neJZu.....7LrIbs*"
},
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36"
}
}
}
// npx playwright install chromium
import { chromium } from 'playwright';
import { CapMonsterCloudClientFactory, ClientOptions, TenDIRequest } from '@zennolab_com/capmonstercloud-client';
// Substitua pelos seus valores
const API_KEY = "YOUR_API_KEY";
const WEBSITE_URL = "https://example.com";
async function solveTenDIOnPage() {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();
// 1. Abrimos a página
await page.goto(WEBSITE_URL, { waitUntil: 'networkidle' });
// 2. Esperamos o captcha aparecer (ex.: input ou iframe)
await page.waitForSelector('#tendi_response, iframe[src*="tendi"], input[name="tendi_response"]', { timeout: 15000 });
// Se necessário, pode extrair o websiteKey da página
const WEBSITE_KEY = await page.evaluate(() => {
// Exemplo: sitekey pode estar em um atributo data ou em uma variável global
const el = document.querySelector('#tendi_response') || document.querySelector('div[data-sitekey]');
return el?.getAttribute('data-sitekey') || window.TenDI_siteKey || "183268248";
});
console.log("Website key detected:", WEBSITE_KEY);
const client = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: API_KEY })
);
// 3. Criamos a tarefa TenDI
const tenDIRequest = new TenDIRequest({
websiteURL: page.url(),
websiteKey: WEBSITE_KEY,
});
const balance = await client.getBalance();
console.log("Balance:", balance);
// 4. Resolvemos o captcha
const solution = await client.Solve(tenDIRequest);
console.log("Solution:", solution);
const { ticket, randstr } = solution.solution.data;
// 5. Formas de inserir o resultado
await page.evaluate(({ ticket, randstr }) => {
// Inserção no input
const inputSelectors = ['#tendi_response', 'input[name="tendi_response"]', 'input[type="hidden"]'];
let inserted = false;
for (const sel of inputSelectors) {
const input = document.querySelector(sel);
if (input) {
input.value = ticket;
input.dispatchEvent(new Event('input', { bubbles: true }));
const form = input.closest('form');
if (form) form.submit();
inserted = true;
break;
}
}
// Função callback JS
if (typeof window.onCaptchaSolved === 'function') {
window.onCaptchaSolved(ticket, randstr);
inserted = true;
}
// Se não houver input nem callback
if (!inserted) {
window._tenDITicket = ticket;
window._tenDIRandStr = randstr;
console.log("Ticket and randstr saved to window._tenDITicket and window._tenDIRandStr");
}
}, { ticket, randstr });
await page.waitForTimeout(5000);
await browser.close();
}
solveTenDIOnPage().catch(console.error);
Como funciona a integração
Passo 1: Carregar o JS do captcha
O script deve ser carregado dinamicamente:
<script src="https://ca.turing.captcha.qcloud.com/TJNCaptcha-global.js"></script>Carregamentos não padrão ou cache podem fazer o captcha funcionar incorretamente.
Passo 2: Criar o objeto TencentCaptcha
Após carregar o JS, aparece uma classe global:
<script src="new TencentCaptcha(domElement, CaptchaAppId, callback, options);"></script>Parâmetros:
domElement - Container onde o checkbox/iframe será inserido
CaptchaAppId - Seu ID
callback - O que fazer após a verificação
options - Configurações visuais (opcional)
Passo 3: Chamar o método .show()
captcha.show();Mostra o captcha. Pode ser chamado várias vezes.
Passo 4: Processar o resultado
Callback recebe um objeto:
{
ret: 0, // 0 -- sucesso, 2 -- usuário fechou a janela
ticket: "...", // necessário pelo servidor
randstr: "...", // também necessário pelo servidor
errorCode: 1001, // se o captcha não carregou
errorMessage: "..." // mensagem de erro
}No servidor, sempre execute a verificação do ticket.
"Modo de emergência"
Se o captcha não carregar (ex.: CDN indisponível), você pode gerar automaticamente um 'ticket de emergência' para não interromper o processo de negócio.
Cenário:
trerror_<errorcode>_<appid>_<timestamp>Criptografia do AppId (opcional)
Para proteção máxima, você pode enviar para o captcha uma versão criptografada do AppId em vez da versão aberta:
aidEncrypted = Base64(IV + AES256(AppId & timestamp & ttl))Necessário:
Exemplo de criptografia server-side (Python)
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import base64
def encrypt(plaintext, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(plaintext.encode(), AES.block_size))
return base64.b64encode(iv + ciphertext).decode("utf-8")Validação no servidor
Passo 1. Configurar acesso à API
No painel de gestão de chaves (CAM / API Key Management), obtenha SecretId e SecretKey para a API. Necessário para requisições assinadas.
Passo 2. Chamar API DescribeCaptchaResult
Após o cliente devolver ticket e randstr, o servidor envia a requisição:
Parâmetros:
CaptchaType - 9 (valor fixo)
Ticket - string — ticket retornado do cliente
Randstr - string — randstr retornado do cliente
CaptchaAppId - seu AppId
AppSecretKey - sua chave secreta
UserIp - IP do usuário (recomendado)
Passo 3. Processar resposta
A API retorna:
Se CaptchaCode === OK, o usuário é considerado verificado. Caso contrário — rejeitar.
Exemplo — verificação de ticket em Node.js
import { v20190722 as captcha } from "@tencentcloud/tencentcloud-sdk-nodejs";
const client = new captcha.Client({
credential: {
secretId: "YOUR_SECRET_ID",
secretKey: "YOUR_SECRET_KEY"
},
region: "ap-project", // região, se necessário
});
async function verifyCaptcha(ticket, randstr, userIp) {
const params = {
CaptchaType: 9,
Ticket: ticket,
Randstr: randstr,
CaptchaAppId: YOUR_APP_ID,
AppSecretKey: "YOUR_APP_SECRET_KEY",
UserIp: userIp
};
const resp = await client.DescribeCaptchaResult(params);
const code = resp.Response.CaptchaCode;
return code === 0;
}Mais informações sobre como conectar Tencent CAPTCHA ao seu site podem ser encontradas na documentação oficial.