Cloudflare Turnstile es la alternativa CAPTCHA de mayor crecimiento. Para resolverlo con CaptchaAI, necesitas el sitekey y la URL de la página. Esta guía cubre todas las formas de encontrar el sitekey, desde simples consultas DOM hasta interceptar llamadas de renderizado de JavaScript.
Dónde viven las claves de sitio de Turnstile
Las sitekeys de Turnstile aparecen en tres lugares:
- El atributo
data-sitekeyen elementos.cf-turnstile - La llamada JavaScript
turnstile.render() - La URL del
srcdel iframe de Turnstile
Método 1: atributo DOM
// Browser console
document.querySelectorAll('.cf-turnstile').forEach((el, i) => {
console.log(`Turnstile ${i}:`, {
sitekey: el.getAttribute('data-sitekey'),
action: el.getAttribute('data-action'),
cData: el.getAttribute('data-cdata'),
theme: el.getAttribute('data-theme'),
});
});
Python (HTML estático)
import re
import requests
html = requests.get("https://staging.example.com/qa-login").text
matches = re.findall(
r'class=["\'][^"\']*cf-turnstile[^"\']*["\'][^>]*data-sitekey=["\']([^"\']+)',
html
)
for sk in matches:
print(f"Sitekey: {sk}")
Python (Selenium)
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://staging.example.com/qa-login")
widgets = driver.find_elements(By.CSS_SELECTOR, ".cf-turnstile")
for w in widgets:
sitekey = w.get_attribute("data-sitekey")
action = w.get_attribute("data-action")
print(f"Sitekey: {sitekey}, Action: {action}")
Método 2: llamada de renderizado de JavaScript
Algunos sitios representan Turnstile mediante programación:
turnstile.render('#captcha-container', {
sitekey: '0x4AAAAAAAB...',
callback: function(token) {
document.getElementById('cf-token').value = token;
},
});
Extracto de la fuente de la página:
# Find turnstile.render calls
render_match = re.search(
r'turnstile\.render\s*\([^,]*,\s*\{([^}]+)\}',
html
)
if render_match:
config = render_match.group(1)
sk = re.search(r'sitekey\s*:\s*["\']([^"\']+)', config)
if sk:
print(f"Sitekey from render: {sk.group(1)}")
Intercepción con Puppeteer
// Intercept turnstile.render before page loads
await page.evaluateOnNewDocument(() => {
window.__turnstileParams = [];
const origRender = window.turnstile?.render;
Object.defineProperty(window, 'turnstile', {
set(val) {
this._turnstile = val;
const orig = val.render;
val.render = function(container, params) {
window.__turnstileParams.push(params);
console.log('Turnstile render:', JSON.stringify(params));
return orig.apply(this, arguments);
};
},
get() { return this._turnstile; }
});
});
await page.goto('https://staging.example.com/qa-login', { waitUntil: 'networkidle2' });
const params = await page.evaluate(() => window.__turnstileParams);
console.log('Captured Turnstile params:', params);
Método 3: origen de iframe
Turnstile genera un iframe. La clave del sitio está en su src:
document.querySelectorAll('iframe').forEach(iframe => {
if (iframe.src.includes('challenges.cloudflare.com')) {
console.log('Turnstile iframe:', iframe.src);
const match = iframe.src.match(/sitekey=([A-Za-z0-9_-]+)/);
if (match) console.log('Sitekey:', match[1]);
}
});
Resolviendo Turnstile con CaptchaAI
Python
import requests
import time
API_KEY = "YOUR_API_KEY"
SITEKEY = "0x4AAAAAAAB..."
PAGE_URL = "https://staging.example.com/qa-login"
# Submit
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": SITEKEY,
"pageurl": PAGE_URL,
"json": "1",
}).json()
if resp["status"] != 1:
raise Exception(f"Submit error: {resp['request']}")
task_id = resp["request"]
# Poll
for _ in range(24):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": "1"
}).json()
if result["status"] == 1:
token = result["request"]
print(f"Turnstile token: {token[:50]}...")
break
if result["request"] != "CAPCHA_NOT_READY":
raise Exception(f"Error: {result['request']}")
JavaScript
const axios = require('axios');
const submit = await axios.post('https://ocr.captchaai.com/in.php', null, {
params: {
key: 'YOUR_API_KEY',
method: 'turnstile',
sitekey: '0x4AAAAAAAB...',
pageurl: 'https://staging.example.com/qa-login',
json: 1,
}
});
const taskId = submit.data.request;
// Poll for result
let token = null;
for (let i = 0; i < 24; i++) {
await new Promise(r => setTimeout(r, 5000));
const poll = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: 'YOUR_API_KEY', action: 'get', id: taskId, json: 1 }
});
if (poll.data.status === 1) {
token = poll.data.request;
break;
}
}
console.log(`Token: ${token.substring(0, 50)}...`);
Inyección de tokens
Turnstile almacena su token en una entrada oculta llamada cf-turnstile-response:
# Selenium
driver.execute_script("""
const input = document.querySelector('input[name="cf-turnstile-response"]');
if (input) input.value = arguments[0];
// Also set in the Turnstile widget's callback
const widget = document.querySelector('.cf-turnstile');
const callbackName = widget?.getAttribute('data-callback');
if (callbackName && typeof window[callbackName] === 'function') {
window[callbackName](arguments[0]);
}
""", token)
Solución de problemas
| Problema | Causa | Solución |
|---|---|---|
No se encontró ningún elemento .cf-turnstile |
Renderizado dinámicamente | Espera a que se cargue la página o usa MutationObserver |
| Sitekey vacía | Configurada mediante la API de JavaScript | Busca turnstile.render en los scripts |
| Token rechazado | URL de página o sitekey incorrecta | Verifica que ambos valores coincidan con el sitio de destino |
Parámetro method incorrecto |
Usando userrecaptcha para Turnstile |
Usa method=turnstile |
Preguntas frecuentes
¿Es Turnstile más difícil de resolver que reCAPTCHA?
No. CaptchaAI maneja ambos. Turnstile normalmente se resuelve en 10 a 25 segundos, comparable a reCAPTCHA v2.
¿Turnstile tiene un modo invisible?
Turnstile tiene modos "administrados" y "no interactivos" que no muestran un widget visible. Los métodos de extracción de claves del sitio funcionan igual.
Resuelve CAPTCHA Cloudflare Turnstile con CaptchaAI
Obtén tu clave API en captchaai.com.
Guías relacionadas
- Extracción de parámetros reCAPTCHA de la fuente de la página
- Cloudflare Turnstile vs reCAPTCHA vs hCaptcha