Explicaciones Técnicas

Guía de la cookie qa_validation_cookie de Cloudflare Challenge

No puedes copiar la cookie de acceso de Cloudflare desde tu navegador y pegarla en un scraper: sólo aparece al superar el challenge y viene atada a la IP y al User-Agent que lo resolvieron. Esa cookie —aquí la llamamos qa_validation_cookie— convierte un 403 o un 503 en un 200. Veamos cómo la genera Cloudflare y cómo obtenerla con CaptchaAI.

Esta guía asume que trabajas sobre sitios propios o con permiso, y que respetas los términos de servicio y la normativa de protección de datos aplicable. Resolver el challenge es el producto; el uso responsable corre de tu cuenta.


Qué pasa cuando Cloudflare te marca como sospechoso

Es una página intersticial que Cloudflare intercala antes del contenido. El flujo es siempre el mismo:

  1. Solicitas una página protegida por Cloudflare.
  2. Cloudflare evalúa señales de riesgo: reputación de la IP, encabezados HTTP y la huella TLS del cliente.
  3. Si te marca, responde con un 403 o un 503 que sirve una página de challenge en JavaScript.
  4. Ejecuta comprobaciones del navegador y, según el nivel, muestra un widget Turnstile.
  5. Al superarla, Cloudflare establece qa_validation_cookie y te redirige a la URL original.
  6. Las siguientes solicitudes que llevan la cookie pasan sin volver a ver el challenge.

Sin resolver el challenge no hay cookie que extraer.


Los tres niveles de Cloudflare Challenge

Cloudflare sirve tres niveles:

Nivel Código de respuesta Interacción del usuario Descripción
JS Challenge 503 Ninguna Sólo ejecución de JavaScript
Managed Challenge 403 Puede que sí Cloudflare decide: muestra Turnstile o pasa en silencio
Interactive Challenge 403 Siempre muestra un widget Turnstile

CaptchaAI resuelve los tres con el solver de Cloudflare Challenge.


Al superar el challenge recibes una cookie con estas propiedades:

Propiedad Detalle
Nombre qa_validation_cookie
Dominio Dominio del sitio de destino (por ejemplo, .example.com)
Ruta /
Duración Normalmente de 30 minutos a 24 horas
HttpOnly
Secure Sí (sólo HTTPS)
SameSite None

Va ligada a tu identidad de red:

  • Dirección IP: usar la cookie desde una IP distinta a la que resolvió el challenge suele fallar.
  • User-Agent: debe coincidir con el UA empleado durante la resolución.
  • Huella TLS: algunas configuraciones la vinculan al TLS ClientHello del cliente.

En la práctica, estos tres factores explican casi todos los rechazos: una cookie que "funcionaba" deja de valer en cuanto cambias de máquina, de red o de cabecera.


Resolver el challenge con CaptchaAI

Obtienes el token de Turnstile: envías la tarea a in.php y consultas res.php hasta tenerlo.

Python

import requests
import time

API_KEY = "YOUR_API_KEY"
TARGET_URL = "https://example.com/protected-page"

# Submit Cloudflare Challenge task
resp = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "turnstile",
    "sitekey": "0x0000000000000000000000",  # may be generic for CF challenge
    "pageurl": TARGET_URL,
    "json": "1",
}).json()

if resp["status"] != 1:
    raise Exception(f"Submit error: {resp['request']}")

task_id = resp["request"]
print(f"Task ID: {task_id}")

# Poll for result
for _ in range(30):
    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"Token received: {token[:50]}...")
        break
    if result["request"] != "CAPCHA_NOT_READY":
        raise Exception(f"Error: {result['request']}")

JavaScript

const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const TARGET_URL = 'https://example.com/protected-page';

const submit = await axios.post('https://ocr.captchaai.com/in.php', null, {
  params: {
    key: API_KEY,
    method: 'turnstile',
    sitekey: '0x0000000000000000000000',
    pageurl: TARGET_URL,
    json: 1,
  }
});
const taskId = submit.data.request;

// Poll
let token = null;
for (let i = 0; i < 30; i++) {
  await new Promise(r => setTimeout(r, 5000));
  const poll = await axios.get('https://ocr.captchaai.com/res.php', {
    params: { key: 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)}...`);

El token no basta: inyéctalo en el campo de respuesta de Turnstile y deja que Cloudflare procese el envío para recibir qa_validation_cookie. Aquí necesitas un navegador real (Selenium o Puppeteer).

# With Selenium
from selenium import webdriver

driver = webdriver.Chrome()
driver.get(TARGET_URL)  # Load the challenge page

# Inject token into Turnstile response field
driver.execute_script("""
    const input = document.querySelector('input[name="cf-turnstile-response"]');
    if (input) input.value = arguments[0];

    // Trigger form submit or callback
    const form = document.querySelector('form');
    if (form) form.submit();
""", token)

# Wait for redirect and extract cookies
import time
time.sleep(3)
cookies = driver.get_cookies()
qa_validation_cookie = next(
    (c for c in cookies if c['name'] == 'qa_validation_cookie'), None
)
if qa_validation_cookie:
    print(f"qa_validation_cookie: {qa_validation_cookie['value'][:30]}...")

Traslada la cookie a una sesión de requests. Usa el mismo User-Agent de la resolución; si no coincide, vuelve el challenge.

session = requests.Session()
session.cookies.set("qa_validation_cookie", qa_validation_cookie["value"], domain=".example.com")
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})

# Now access protected pages
resp = session.get("https://example.com/api/data")
print(resp.status_code)  # 200

Si repartes el trabajo entre varios workers, guarda la cookie y su expiry en un almacén compartido como Redis: así resuelves el challenge una vez y todos los procesos reutilizan la misma cookie hasta que caduca.


qa_validation_cookie caduca; comprueba su validez y renueva antes de que expire, sin esperar al primer 403:

import datetime

def is_cookie_valid(cookie):
    if not cookie:
        return False
    expiry = cookie.get("expiry", 0)
    return datetime.datetime.now().timestamp() < expiry - 60  # 60s buffer

def get_or_refresh_clearance(driver, target_url, solve_func):
    cookies = driver.get_cookies()
    cf = next((c for c in cookies if c["name"] == "qa_validation_cookie"), None)
    if is_cookie_valid(cf):
        return cf["value"]

    # Re-solve
    token = solve_func(target_url)
    # ... inject and extract new cookie

Ejemplo típico: para monitorizar precios en un marketplace regional, resuelve una vez, reutilízala mientras dure y renueva al agotarse el margen.


No toda petición necesita un challenge nuevo. Cada resolución consume un thread de tu plan y suma latencia, así que conviene exprimir cada cookie mientras siga válida. Vuelve a resolver sólo cuando se cumpla alguna de estas condiciones:

  • La cookie ha caducado, según el campo expiry.
  • Cambias de IP o de salida de red respecto a la que resolvió el challenge.
  • El sitio empieza a devolver 403 pese a enviar una cookie que parecía válida.

Este último caso suele indicar que el sitio endureció su configuración de Cloudflare o rotó el secreto; volver a resolver genera una cookie fresca sin más cambios en tu código.


Síntoma Causa probable Cómo resolverlo
La cookie se rechaza tras resolver La IP no coincide Usa el mismo proxy para resolver y para las solicitudes
La cookie caduca enseguida TTL corto fijado por el sitio Resuelve antes de que expire; revisa el campo expiry
403 con una cookie válida El User-Agent no coincide Iguala el UA entre la sesión de resolución y la de solicitud
La página de challenge no carga JavaScript deshabilitado Usa un navegador completo (Selenium, Puppeteer)

Si un síntoma persiste después de igualar la IP y el User-Agent, vuelve a resolver el challenge: suele salir más a cuenta que depurar una cookie ya inservible.


Preguntas frecuentes

Porque va atada a la IP y al User-Agent que resolvieron el challenge; con otra IP u otra cabecera, Cloudflare la invalida.

Depende: la IP que resuelve y la que reutiliza deben ser la misma. Si ambas salen por la misma red, no necesitas nada extra.

¿CaptchaAI resuelve los tres niveles de Cloudflare Challenge?

Sí. El solver cubre el JS Challenge, el Managed Challenge y el Interactive Challenge, sin que detectes el nivel por adelantado.

¿Puedo saltarme el navegador y trabajar sólo con la API?

No del todo. La API te da el token de Turnstile, pero para que Cloudflare emita qa_validation_cookie alguien tiene que inyectar ese token en la página y enviar el formulario, y eso exige un navegador que ejecute JavaScript, como Selenium o Puppeteer.

Revisa que la IP y el User-Agent coincidan con los de la resolución; si coinciden y aun así falla, lo más probable es que la cookie haya caducado o que el sitio la rechace, así que resuelve de nuevo para obtener una fresca.


Resuelve Cloudflare Challenge con CaptchaAI

Obtén tu clave API en captchaai.com y genera cookies de acceso válidas resolviendo el challenge, sin copiar sesiones a mano.


Guías relacionadas

Los comentarios están deshabilitados para este artículo.