So Sánh

Giải thích về reCAPTCHA v2 và reCAPTCHA vô hình

Cả hai đều là biến thể reCAPTCHA v2 sử dụng cùng một công nghệ cơ bản. Phiên bản hộp kiểm hiển thị "Tôi không phải là người máy" và có thể hiển thị các lưới hình ảnh. Phiên bản ẩn tự động kích hoạt các hành động của người dùng (nhấp vào nút, gửi biểu mẫu hoặc tải trang) mà không có tiện ích hiển thị. Để giải quyết CaptchaAI, điểm khác biệt duy nhất là thêm invisible=1 vào yêu cầu của bạn — nhưng quy trình đưa mã thông báo khác biệt đáng kể.


So sánh song song

tính năng Hộp kiểm v2 v2 Vô hình
Tiện ích hiển thị Có - hộp kiểm "Tôi không phải là robot" Không — ẩn với người dùng
Cơ chế kích hoạt Hộp kiểm nhấp chuột của người dùng Nhấp vào nút, gửi biểu mẫu hoặc tải trang
Thử thách hình ảnh Hiển thị khi Google nghi ngờ bot Cửa sổ bật lên ở góc dưới bên phải khi nghi ngờ
Trải nghiệm người dùng Ma sát vừa phải Ma sát Low/zero
Thực hiện Thêm div g-recaptcha vào trang Thêm data-callback vào nút hoặc grecaptcha.execute()
Định dạng khóa trang web Tương tự như vô hình Tương tự như hộp kiểm
Trường mã thông báo g-recaptcha-response g-recaptcha-response
Chức năng gọi lại Tùy chọn Hầu như luôn luôn cần thiết
Phương pháp CaptchaAI method=userrecaptcha method=userrecaptcha + invisible=1
Tuổi thọ của mã thông báo 120 giây 120 giây
Giải quyết thời gian 10-30 giây 10-25 giây

Cách mỗi thứ xuất hiện trong HTML

Hộp kiểm v2

<!-- Standard checkbox widget -->
<div class="g-recaptcha"
     data-sitekey="6Le-wvkSAAAAAPBMRTvw..."
     data-callback="onSubmit">
</div>

<!-- Widget renders as: -->
<!-- [✓] I'm not a robot     reCAPTCHA logo -->

Người dùng nhìn thấy và tương tác với hộp kiểm. Nếu Google nghi ngờ thì thử thách lưới hình ảnh sẽ xuất hiện nội tuyến.

v2 Vô hình

<!-- Pattern 1: Invisible widget on a button -->
<button class="g-recaptcha"
        data-sitekey="6Le-wvkSAAAAAPBMRTvw..."
        data-callback="onSubmit"
        data-size="invisible">
  Submit
</button>

<!-- Pattern 2: Invisible div (programmatic trigger) -->
<div class="g-recaptcha"
     data-sitekey="6Le-wvkSAAAAAPBMRTvw..."
     data-size="invisible"
     data-callback="onSubmit">
</div>

<!-- Pattern 3: Programmatic render -->
<script>
  grecaptcha.render('submit-btn', {
    sitekey: '6Le-wvkSAAAAAPBMRTvw...',
    callback: onSubmit,
    size: 'invisible'
  });
</script>

Không có tiện ích hiển thị. reCAPTCHA kích hoạt khi người dùng kích hoạt phần tử được chỉ định hoặc khi grecaptcha.execute() được gọi.


Cách phát hiện biến thể nào trên một trang

Phát hiện Python:

import requests
from bs4 import BeautifulSoup
import re

def detect_recaptcha_variant(url):
    resp = requests.get(url)
    soup = BeautifulSoup(resp.text, "html.parser")

    # Check for invisible indicators
    invisible_widget = soup.find(attrs={"data-size": "invisible", "class": "g-recaptcha"})
    if invisible_widget:
        return {
            "variant": "invisible",
            "sitekey": invisible_widget.get("data-sitekey"),
            "callback": invisible_widget.get("data-callback")
        }

    # Check for programmatic invisible in scripts
    for script in soup.find_all("script"):
        if script.string and "invisible" in str(script.string):
            key_match = re.search(r"sitekey['\"]?\s*[:=]\s*['\"]([^'\"]+)", script.string)
            if key_match:
                return {
                    "variant": "invisible-programmatic",
                    "sitekey": key_match.group(1),
                    "callback": "check grecaptcha.render() call"
                }

    # Check for standard checkbox
    checkbox_widget = soup.find(class_="g-recaptcha")
    if checkbox_widget:
        return {
            "variant": "checkbox",
            "sitekey": checkbox_widget.get("data-sitekey"),
            "callback": checkbox_widget.get("data-callback")
        }

    return None

result = detect_recaptcha_variant("https://staging.example.com/qa-login")
print(result)

Phát hiện Node.js:

const axios = require("axios");
const cheerio = require("cheerio");

async function detectRecaptchaVariant(url) {
  const { data } = await axios.get(url);
  const $ = cheerio.load(data);

  // Check for invisible
  const invisible = $(".g-recaptcha[data-size='invisible']");
  if (invisible.length) {
    return {
      variant: "invisible",
      sitekey: invisible.attr("data-sitekey"),
      callback: invisible.attr("data-callback"),
    };
  }

  // Check scripts for programmatic invisible
  const scripts = $("script")
    .map((_, el) => $(el).html())
    .get()
    .join("\n");
  if (scripts.includes("invisible")) {
    const keyMatch = scripts.match(/sitekey['"]?\s*[:=]\s*['"]([^'"]+)/);
    if (keyMatch) {
      return {
        variant: "invisible-programmatic",
        sitekey: keyMatch[1],
        callback: "check render call",
      };
    }
  }

  // Check for standard checkbox
  const checkbox = $(".g-recaptcha");
  if (checkbox.length) {
    return {
      variant: "checkbox",
      sitekey: checkbox.attr("data-sitekey"),
      callback: checkbox.attr("data-callback"),
    };
  }

  return null;
}

Kiểm tra bảng điều khiển trình duyệt nhanh:

const el = document.querySelector('[data-size="invisible"]');
console.log(el ? "Invisible reCAPTCHA" : "Checkbox reCAPTCHA");
Tín hiệu phát hiện Hộp kiểm v2 v2 Vô hình
data-size="invisible" Không có mặt hiện tại
Hộp kiểm hiển thị trên trang Không
grecaptcha.execute() đã gọi Không (số nhấp chuột của người dùng) Có (có lập trình)
Vị trí bật lên thách thức Hộp kiểm nội tuyến, bên dưới Góc dưới bên phải của trang

Giải quyết bằng CaptchaAI

Hộp kiểm v2

import requests
import time

resp = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY",
    "method": "userrecaptcha",
    "googlekey": "6Le-wvkSAAAA...",
    "pageurl": "https://example.com/form"
})
task_id = resp.text.split("|")[1]

for _ in range(60):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": "YOUR_API_KEY", "action": "get", "id": task_id
    })
    if result.text.startswith("OK|"):
        token = result.text.split("|")[1]
        break

v2 Vô hình

import requests
import time

resp = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY",
    "method": "userrecaptcha",
    "googlekey": "6Le-wvkSAAAA...",
    "pageurl": "https://example.com/form",
    "invisible": 1  # Only parameter difference
})
task_id = resp.text.split("|")[1]

for _ in range(60):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": "YOUR_API_KEY", "action": "get", "id": task_id
    })
    if result.text.startswith("OK|"):
        token = result.text.split("|")[1]
        break

Tiêm mã thông báo - sự khác biệt quan trọng

Hộp kiểm v2: Trường ẩn thường là đủ

# Selenium — inject into hidden field
driver.execute_script(
    f'document.getElementById("g-recaptcha-response").value = "{token}";'
)

# If the page uses a callback, also call it
callback = driver.find_element("css selector", ".g-recaptcha").get_attribute("data-callback")
if callback:
    driver.execute_script(f'{callback}("{token}");')

v2 Vô hình: Hầu như luôn cần phải gọi lại

# Selenium — inject AND call the callback
driver.execute_script(
    f'document.getElementById("g-recaptcha-response").value = "{token}";'
)

# CRITICAL: Invisible reCAPTCHA almost always requires calling the callback
callback_name = driver.find_element(
    "css selector", ".g-recaptcha[data-size='invisible']"
).get_attribute("data-callback")

driver.execute_script(f'{callback_name}("{token}");')
// Puppeteer — invisible callback injection
await page.evaluate((tok) => {
  // Set the hidden field
  document.getElementById("g-recaptcha-response").value = tok;

  // Find and call the callback function
  const widget = document.querySelector("[data-size='invisible']");
  const cbName = widget?.getAttribute("data-callback");
  if (cbName && typeof window[cbName] === "function") {
    window[cbName](tok);
  }
}, token);

Sự khác biệt chính: Biểu mẫu hộp kiểm v2 thường chỉ hoạt động với thao tác chèn trường ẩn vì nhấp chuột của người dùng vào hộp kiểm đã đăng ký lệnh gọi lại. ReCAPTCHA vô hình không bao giờ có lượt nhấp chuột đó — lệnh gọi lại phải được gọi một cách rõ ràng.


Bộ giải phổ quát cho cả hai biến thể

import requests
import time
from bs4 import BeautifulSoup

class RecaptchaV2UniversalSolver:
    def __init__(self, api_key):
        self.api_key = api_key

    def detect_and_solve(self, page_url, page_html=None):
        if not page_html:
            page_html = requests.get(page_url).text

        soup = BeautifulSoup(page_html, "html.parser")

        # Detect variant
        invisible = soup.find(attrs={"data-size": "invisible", "class": "g-recaptcha"})
        widget = invisible or soup.find(class_="g-recaptcha")

        if not widget:
            raise Exception("No reCAPTCHA widget found")

        sitekey = widget.get("data-sitekey")
        is_invisible = invisible is not None
        callback = widget.get("data-callback")

        params = {
            "key": self.api_key,
            "method": "userrecaptcha",
            "googlekey": sitekey,
            "pageurl": page_url
        }
        if is_invisible:
            params["invisible"] = 1

        resp = requests.get("https://ocr.captchaai.com/in.php", params=params)
        if not resp.text.startswith("OK|"):
            raise Exception(f"Submit failed: {resp.text}")

        task_id = resp.text.split("|")[1]
        for _ in range(60):
            time.sleep(5)
            result = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": self.api_key, "action": "get", "id": task_id
            })
            if result.text.startswith("OK|"):
                return {
                    "token": result.text.split("|")[1],
                    "variant": "invisible" if is_invisible else "checkbox",
                    "callback": callback,
                    "sitekey": sitekey
                }
            if result.text != "CAPCHA_NOT_READY":
                raise Exception(f"Solve error: {result.text}")

        raise Exception("Timed out")

# Usage
solver = RecaptchaV2UniversalSolver("YOUR_API_KEY")
result = solver.detect_and_solve("https://staging.example.com/qa-login")
print(f"Variant: {result['variant']}, Callback: {result['callback']}")

Khắc phục sự cố

vấn đề Sửa hộp kiểm Sửa chữa vô hình
Mã thông báo không được chấp nhận Đưa vào trường g-recaptcha-response Tiêm VÀ gọi hàm data-callback
Không tìm thấy tiện ích Tìm lớp .g-recaptcha Kiểm tra các cuộc gọi kết xuất data-size="invisible" hoặc tập lệnh
Gửi biểu mẫu nhưng không thành công Kiểm tra xem cuộc gọi lại có được mong đợi không Gọi lại hầu như luôn được yêu cầu - tìm và gọi nó
Trang tải lại sau khi tiêm Xác thực JavaScript không thành công Gọi lại trước trình kích hoạt tự động gửi biểu mẫu

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

ReCAPTCHA vô hình có khó giải quyết hơn không?

Không. Quá trình giải quyết thông qua CaptchaAI gần như giống hệt nhau. Việc thêm invisible=1 vào yêu cầu của bạn là thay đổi duy nhất. Thử thách thêm nằm ở phía tiêm: bạn phải tìm và thực thi chức năng gọi lại.

Cả hai đều sử dụng cùng một định dạng khóa trang web phải không?

Vâng. Định dạng khóa trang web giống hệt nhau. Bạn không thể chỉ biết biến thể chỉ từ khóa trang web — hãy kiểm tra data-size="invisible" trong HTML.

ReCAPTCHA vô hình vẫn hiển thị các thách thức về hình ảnh phải không?

Vâng. Khi Google phát hiện hành vi đáng ngờ, reCAPTCHA vô hình sẽ hiển thị cửa sổ bật lên thử thách hình ảnh ở góc dưới cùng bên phải của trang. Đây là lý do tại sao bạn vẫn cần CaptchaAI - phiên bản vô hình vẫn có thể đưa ra những thách thức.

Một trang web có thể chuyển đổi giữa hộp kiểm và ẩn không?

Vâng. Đây là sự thay đổi cấu hình ở phía cuối trang web — cùng một khóa trang web, cách triển khai khác nhau. Một số trang web sử dụng hộp kiểm trên máy tính để bàn và ẩn trên thiết bị di động. Luôn phát hiện biến thể một cách linh hoạt.

Giải quyết cái nào nhanh hơn?

Các giải pháp vô hình thường nhanh hơn một chút (10-25 giây so với 10-30 giây) vì chúng có xu hướng gây ra ít thử thách hình ảnh hơn. Nhưng sự khác biệt là rất nhỏ.


Hướng dẫn liên quan

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