Phân Tích Kỹ Thuật

Hướng dẫn trích xuất URL bframe và neo reCAPTCHA

reCAPTCHA hiển thị bên trong hai iframe lồng nhau: iframe anchor (chứa tiện ích hộp kiểm) và iframe bframe (chứa thử thách hình ảnh). Các iframe này chứa các tham số được mã hóa mà một số quy trình tự động hóa nâng cao cần trích xuất. Hướng dẫn này giải thích kiến ​​trúc iframe, định dạng tham số và kỹ thuật trích xuất.


kiến trúc 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)

Khung nội tuyến neo

Khung nội tuyến cố định chứa tiện ích hộp kiểm và phân tích rủi ro ban đầu:

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

Khung nội tuyến Bframe

Khung nội tuyến bframe chứa thử thách hình ảnh (chỉ được tải khi nhấp vào hộp kiểm kích hoạt thử thách):

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

Tham số URL neo

tham số Tên Mô tả
k Khóa trang web Khóa trang web reCAPTCHA
co Nguồn gốc được mã hóa Nguồn gốc được mã hóa Base64 (giao thức + miền + cổng)
v Phiên bản Băm phiên bản gói JavaScript reCAPTCHA
hl Ngôn ngữ Mã ngôn ngữ thách thức
size Kích thước normal, compact hoặc invisible
cb Gọi lại Mã định danh hàm gọi lại duy nhất
theme chủ đề light hoặc dark
ar tỷ lệ khung hình Hiển thị cờ tỷ lệ khung hình

Giải mã tham số co

Tham số co chứa nguồn gốc được mã hóa base64:

import base64

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

Điều này cho thấy miền gốc mà reCAPTCHA đã được định cấu hình.


Trích xuất URL neo và bframe

Trích xuất Python từ nguồn trang

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']}")

Trích xuất 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);

Trích xuất Selenium (trang động)

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

Khi bạn cần URL Anchor/bframe

Hầu hết các quy trình tự động hóa KHÔNG cần URL neo hoặc bframe. API CaptchaAI tiêu chuẩn chỉ yêu cầu sitekeypageurl. Tuy nhiên, URL Anchor/bframe rất hữu ích cho:

1. Xác minh khóa trang web chính xác

Khi một trang có nhiều phiên bản reCAPTCHA hoặc khóa trang web được tải động:

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

2. Xác định phiên bản 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. Phù hợp với nguồn gốc để triển khai theo miền nghiêm ngặt

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

4. Gỡ lỗi giải quyết lỗi

Khi mã thông báo bị từ chối, việc so sánh các tham số URL cố định với yêu cầu bộ giải của bạn có thể cho thấy sự không khớp:

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"]

Giải pháp tiêu chuẩn (khuyến nghị)

Đối với hầu hết các trường hợp sử dụng, hãy bỏ qua việc trích xuất iframe và giải quyết trực tiếp bằng 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

Việc trích xuất Anchor/bframe chỉ cần thiết khi việc giải quyết tiêu chuẩn không thành công do vấn đề về khóa trang web hoặc tên miền yêu cầu điều tra sâu hơn.


Câu hỏi thường gặp

Tôi có cần cung cấp URL neo hoặc bframe cho CaptchaAI không?

Không. CaptchaAI chỉ cần sitekeypageurl. Bộ giải xử lý tương tác neo và bframe trong nội bộ. Việc trích xuất các URL này rất hữu ích cho việc gỡ lỗi nhưng không bắt buộc để giải quyết.

Tại sao iframe bframe không xuất hiện trong nguồn trang?

Khung nội tuyến bframe được tạo động bằng JavaScript của reCAPTCHA khi người dùng nhấp vào hộp kiểm và một thử thách được kích hoạt. Nó không có trong HTML ban đầu. Bạn cần Selenium hoặc Puppeteer để tương tác với tiện ích và nắm bắt URL bframe.

Tham số v trong URL liên kết là gì?

Tham số v là hàm băm phiên bản gói JavaScript reCAPTCHA. Nó thay đổi định kỳ khi Google cập nhật reCAPTCHA. Không cần thiết để giải quyết - CaptchaAI tự động xử lý các khác biệt về phiên bản.

Tham số co có thể giúp gỡ lỗi các vấn đề về miền không?

Vâng. Tham số co là nguồn gốc được mã hóa base64 (giao thức + miền + cổng). Giải mã nó sẽ tiết lộ chính xác reCAPTCHA tên miền nào cho rằng nó đang chạy trên đó. Nếu tên miền này không khớp với tên miền mà bạn đang gửi mã thông báo thì bạn đã phát hiện thấy tên miền không khớp khiến mã thông báo bị từ chối.


Tóm tắt

reCAPTCHA sử dụng hai iframe: neo (tiện ích hộp kiểm) và bframe (thử thách hình ảnh). URL neo chứa khóa trang web, nguồn gốc được mã hóa và hàm băm phiên bản. Để giải tiêu chuẩn vớiCaptchaAI, bạn chỉ cần sitekeypageurl — không cần trích xuất URL iframe. Sử dụng kỹ thuật trích xuất iframe để gỡ lỗi xác minh miền hoặc trích xuất khóa trang web từ các trang được tải động.

bài viết liên quan

Os comentários estão desativados para este artigo.