Explainers

Guía de extracción de URL de reCAPTCHA Anchor y Bframe

reCAPTCHA se representa dentro de dos iframes anidados: el iframe ancla (que contiene el widget de casilla de verificación) y el iframe bframe (que contiene el desafío de imagen). Estos iframes contienen parámetros codificados que algunos flujos de trabajo de automatización avanzados deben extraer. Esta guía explica la arquitectura del iframe, el formato de los parámetros y las técnicas de extracción.


Arquitectura de iframe reCAPTCHA

Target page (staging.example.com/qa-login)
    └── <iframe src="https://www.google.com/recaptcha/api2/anchor?...">
        │   ← Anchor iframe: "I'm not a robot" checkbox
        │
        └── <iframe src="https://www.google.com/recaptcha/api2/bframe?...">
                ← Bframe iframe: Image challenge grid (loads when clicked)

Marco flotante anclado

El iframe ancla contiene el widget de casilla de verificación y el análisis de riesgo inicial:

https://www.google.com/recaptcha/api2/anchor?
    ar=1
    &k=6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp  ← site key
    &co=aHR0cHM6Ly9leGFtcGxlLmNvbTo0NDM.           ← encoded origin
    &hl=en                                           ← language
    &v=jF2Zb_rr_5sv8dMHoGIn-XxY                    ← reCAPTCHA version
    &size=normal                                     ← widget size
    &cb=89fu2pf0swif                                ← callback ID

marco flotante

El iframe bframe contiene el desafío de la imagen (solo se carga cuando al hacer clic en la casilla de verificación se activa un desafío):

https://www.google.com/recaptcha/api2/bframe?
    hl=en
    &v=jF2Zb_rr_5sv8dMHoGIn-XxY
    &k=6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp

Parámetros de URL de anclaje

Parámetro Nombre Descripción
k Clave del sitio La clave del sitio reCAPTCHA
co origen codificado Origen codificado en Base64 (protocolo + dominio + puerto)
v Versión Hash de versión del paquete JavaScript reCAPTCHA
hl Idioma Código de idioma de desafío
size Tamaño normal, compact o invisible
cb Devolución de llamada Identificador único de función de devolución de llamada
theme Tema light o dark
ar relación de aspecto Indicador de relación de aspecto de la pantalla

Decodificando el parámetro co

El parámetro co contiene el origen codificado en base64:

import base64

co_value = "aHR0cHM6Ly9leGFtcGxlLmNvbTo0NDM."
# Remove trailing period (padding artifact)
decoded = base64.b64decode(co_value.rstrip(".") + "==").decode()
print(decoded)  # "https://example.com:443"

Esto revela el dominio de origen para el que se configuró reCAPTCHA.


Extracción de URL de anclaje y bframe

Extracción de Python del origen de la página

import requests
from bs4 import BeautifulSoup
from urllib.parse import urlparse, parse_qs
import re
import base64

def extract_recaptcha_iframes(url):
    """Extract reCAPTCHA anchor and bframe iframe URLs and parameters."""
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/120.0.0.0 Safari/537.36",
    }

    response = requests.get(url, headers=headers, timeout=15)
    soup = BeautifulSoup(response.text, "html.parser")

    result = {
        "anchor_url": None,
        "bframe_url": None,
        "site_key": None,
        "origin": None,
        "version": None,
        "language": None,
    }

    # Find anchor iframe
    anchor_iframe = soup.find("iframe", src=re.compile(r"recaptcha.*anchor"))
    if anchor_iframe:
        anchor_url = anchor_iframe.get("src", "")
        result["anchor_url"] = anchor_url

        # Parse parameters
        parsed = urlparse(anchor_url)
        params = parse_qs(parsed.query)

        result["site_key"] = params.get("k", [None])[0]
        result["version"] = params.get("v", [None])[0]
        result["language"] = params.get("hl", [None])[0]

        # Decode origin
        co = params.get("co", [None])[0]
        if co:
            try:
                padded = co.rstrip(".") + "=="
                result["origin"] = base64.b64decode(padded).decode()
            except Exception:
                result["origin"] = co

    # Find bframe iframe (may not be in source — loaded dynamically)
    bframe_iframe = soup.find("iframe", src=re.compile(r"recaptcha.*bframe"))
    if bframe_iframe:
        result["bframe_url"] = bframe_iframe.get("src", "")

    # Construct bframe URL from anchor parameters if not found
    if not result["bframe_url"] and result["site_key"] and result["version"]:
        result["bframe_url"] = (
            f"https://www.google.com/recaptcha/api2/bframe?"
            f"hl={result['language'] or 'en'}"
            f"&v={result['version']}"
            f"&k={result['site_key']}"
        )

    return result

iframes = extract_recaptcha_iframes("https://staging.example.com/qa-login")
print(f"Site key: {iframes['site_key']}")
print(f"Origin: {iframes['origin']}")
print(f"Anchor URL: {iframes['anchor_url']}")

Extracción de Node.js

const axios = require("axios");
const cheerio = require("cheerio");
const { URL } = require("url");

async function extractRecaptchaIframes(pageUrl) {
    const { data: html } = await axios.get(pageUrl, {
        headers: {
            "User-Agent":
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
                "AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36",
        },
        timeout: 15000,
    });

    const $ = cheerio.load(html);
    const result = {
        anchorUrl: null,
        bframeUrl: null,
        siteKey: null,
        origin: null,
        version: null,
    };

    // Find anchor iframe
    const anchorIframe = $("iframe[src*='recaptcha'][src*='anchor']");
    if (anchorIframe.length) {
        const src = anchorIframe.attr("src");
        result.anchorUrl = src;

        const url = new URL(src);
        result.siteKey = url.searchParams.get("k");
        result.version = url.searchParams.get("v");

        // Decode origin
        const co = url.searchParams.get("co");
        if (co) {
            try {
                result.origin = Buffer.from(
                    co.replace(/\.$/, ""), "base64"
                ).toString();
            } catch {}
        }
    }

    // Construct bframe URL
    if (result.siteKey && result.version) {
        result.bframeUrl =
            `https://www.google.com/recaptcha/api2/bframe?` +
            `hl=en&v=${result.version}&k=${result.siteKey}`;
    }

    return result;
}

extractRecaptchaIframes("https://staging.example.com/qa-login").then(console.log);

Extracción de selenio (páginas dinámicas)

from selenium import webdriver
from selenium.webdriver.common.by import By
import time

def extract_iframes_selenium(url):
    """Extract reCAPTCHA iframe URLs from a dynamically loaded page."""
    driver = webdriver.Chrome()
    driver.get(url)
    time.sleep(3)  # Wait for reCAPTCHA to load

    result = {"anchor_url": None, "bframe_url": None}

    # Find all iframes
    iframes = driver.find_elements(By.TAG_NAME, "iframe")

    for iframe in iframes:
        src = iframe.get_attribute("src") or ""
        if "recaptcha" in src and "anchor" in src:
            result["anchor_url"] = src
        elif "recaptcha" in src and "bframe" in src:
            result["bframe_url"] = src

    driver.quit()
    return result

Cuando necesita URL de Anchor/bframe

La mayoría de los flujos de trabajo de automatización NO necesitan URL de anclaje o bframe. La API estándar CaptchaAI solo requiere sitekey y pageurl. Sin embargo, las URL Anchor/bframe son útiles para:

1. Verificar la clave del sitio correcta

Cuando una página tiene varias instancias de reCAPTCHA o la clave del sitio se carga dinámicamente:

# Extract sitekey from anchor URL when it's not in the page HTML
iframes = extract_recaptcha_iframes(url)
sitekey = iframes["site_key"]  # Guaranteed correct from iframe URL

2. Determinar la versión de reCAPTCHA

# The anchor URL reveals the exact reCAPTCHA version
if "/api2/anchor" in anchor_url:
    recaptcha_type = "v2"
elif "/enterprise/anchor" in anchor_url:
    recaptcha_type = "enterprise"

3. Hacer coincidir el origen para implementaciones de dominio estricto

# Decode the origin from the co parameter
origin = decode_co_parameter(iframes["co"])
# Use this origin as the pageurl for the solver

4. La depuración resuelve fallos

Cuando se rechazan los tokens, comparar los parámetros de la URL ancla con su solicitud de solución puede revelar discrepancias:

def debug_solve_params(anchor_url, solver_pageurl, solver_sitekey):
    """Compare anchor params with solver request to find mismatches."""
    parsed = urlparse(anchor_url)
    params = parse_qs(parsed.query)

    issues = []

    # Check sitekey
    anchor_key = params.get("k", [None])[0]
    if anchor_key != solver_sitekey:
        issues.append(f"Sitekey mismatch: anchor={anchor_key}, solver={solver_sitekey}")

    # Check origin
    co = params.get("co", [None])[0]
    if co:
        origin = base64.b64decode(co.rstrip(".") + "==").decode()
        solver_parsed = urlparse(solver_pageurl)
        solver_origin = f"{solver_parsed.scheme}://{solver_parsed.netloc}"
        if origin != solver_origin:
            issues.append(f"Origin mismatch: anchor={origin}, solver={solver_origin}")

    return issues if issues else ["No mismatches found"]

Resolución estándar (recomendada)

Para la mayoría de los casos de uso, omita la extracción de iframe y resuelva directamente con CaptchaAI:

import requests
import time

API_KEY = "YOUR_API_KEY"

# All you need: sitekey + pageurl
submit = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": "6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp",
    "pageurl": "https://staging.example.com/qa-login",
    "json": 1,
})

task_id = submit.json()["request"]

for _ in range(60):
    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.get("status") == 1:
        token = result["request"]
        print(f"Token: {token[:50]}...")
        break

La extracción de Anchor/bframe solo es necesaria cuando la resolución estándar falla debido a problemas de dominio o clave del sitio que requieren una investigación más profunda.


Preguntas frecuentes

¿Debo proporcionar URL de anclaje o bframe a CaptchaAI?

No. CaptchaAI solo necesita sitekey y pageurl. El solucionador maneja internamente la interacción entre anclaje y bframe. Extraer estas URL es útil para depurar, pero no es necesario para resolver.

¿Por qué el iframe bframe no aparece en la fuente de la página?

El iframe bframe se crea dinámicamente mediante JavaScript de reCAPTCHA cuando el usuario hace clic en la casilla de verificación y se activa un desafío. No está presente en el HTML inicial. Necesita Selenium o Puppeteer para interactuar con el widget y capturar la URL del bframe.

¿Qué es el parámetro v en la URL ancla?

El parámetro v es el hash de la versión del paquete JavaScript reCAPTCHA. Cambia periódicamente cuando Google actualiza reCAPTCHA. No es necesario para resolver: CaptchaAI maneja las diferencias de versión automáticamente.

¿Puede el parámetro co ayudar a depurar problemas de dominio?

Sí. El parámetro co es el origen codificado en base64 (protocolo + dominio + puerto). Decodificarlo revela exactamente en qué dominio cree reCAPTCHA que se está ejecutando. Si esto no coincide con el dominio al que envía el token, habrá descubierto que la discrepancia del dominio provoca el rechazo del token.


Resumen

reCAPTCHA utiliza dos iframes: ancla (widget de casilla de verificación) y bframe (desafío de imagen). La URL ancla contiene la clave del sitio, el origen codificado y el hash de la versión. Para la resolución estándar conCaptchaAI, solo necesita sitekey y pageurl; no se requiere extracción de URL de iframe. Utilice técnicas de extracción de iframe para depurar fallas de verificación de dominio o extraer claves de sitio de páginas cargadas dinámicamente.

Artículos relacionados

  • Cómo resolver la devolución de llamada de Recaptcha V2 usando Api
  • Torniquete Recaptcha V2 Manejo en el mismo sitio
  • Mecanismo de devolución de llamada Recaptcha V2
Los comentarios están deshabilitados para este artículo.

Publicaciones relacionadas

Explainers Análisis profundo de la API de evaluación empresarial reCAPTCHA
Explicación clara sobre Análisis profundo de la API de evaluación empresarial re CAPTCHA y lo que implica para automatización, integración y tasas de éxito con...

Explicación clara sobre Análisis profundo de la API de evaluación empresarial re CAPTCHA y lo que implica para...

Apr 28, 2026
Explainers reCAPTCHA v2 Invisible: Detección y resolución de activadores
Explicación clara sobre re CAPTCHA v 2 Invisible: Detección y resolución de desencadenantes y lo que implica para automatización, integración y tasas de éxito c...

Explicación clara sobre re CAPTCHA v 2 Invisible: Detección y resolución de desencadenantes y lo que implica p...

Apr 29, 2026
Explainers Requisitos de sesión y cookies reCAPTCHA para resolver
Explicación clara sobre Requisitos de sesión y cookies re CAPTCHA para resolver y lo que implica para automatización, integración y tasas de éxito con Captcha A...

Explicación clara sobre Requisitos de sesión y cookies re CAPTCHA para resolver y lo que implica para automati...

Apr 20, 2026