Hướng Dẫn API

Cách giải reCAPTCHA Invisible bằng API

Bạn gửi token reCAPTCHA đúng cách nhưng biểu mẫu vẫn báo lỗi hoặc đứng im không submit? Nhiều khả năng bạn đang xử lý reCAPTCHA Invisible y hệt reCAPTCHA v2 checkbox — và đó chính là lý do request bị từ chối. reCAPTCHA Invisible không có ô kiểm; nó tự kích hoạt ngay khi người dùng bấm nút gửi hoặc submit form, chạy ngầm phía sau, rồi chỉ cho trang tiếp tục khi token được xác minh.

Khác biệt duy nhất so với v2 tiêu chuẩn — nhưng là khác biệt quyết định thành-bại — nằm ở bước cuối: cách bạn đưa token vào trang. Hầu hết implementation Invisible dùng một hàm callback JavaScript thay vì field ẩn g-recaptcha-response, nên bạn phải tìm đúng tên callback rồi gọi nó bằng tay. Bài này dành cho dev cần một đoạn code chạy được ngay, không phải bài tổng quan lý thuyết. Toàn bộ luồng gồm bốn phần:

  1. Phát hiện đúng widget Invisible trên trang.
  2. Gửi task tới in.php kèm tham số invisible: 1.
  3. Polling res.php cho tới khi có token.
  4. Đưa token vào trang qua hàm callback (không phải field ẩn).

Chưa chắc site đang chạy Invisible hay v2 checkbox? Xem reCAPTCHA v2 và Invisible khác nhau ở đâu để phân biệt nhanh.


Những gì bạn cần trước khi bắt đầu

  • API key CaptchaAI — lấy tại captchaai.com/api.php
  • Sitekey — đọc từ thuộc tính data-sitekey trên widget hoặc nút bấm
  • Page URL — URL đầy đủ của trang đang chạy reCAPTCHA Invisible
  • Công cụ trình duyệt — Selenium hoặc Puppeteer để thực thi callback

Tình huống quen thuộc với các team QA/automation ở Việt Nam — kể cả những team outsource đang test luồng đăng ký cho khách hàng thương mại điện tử: script gửi task đúng tham số, CaptchaAI trả về token hợp lệ, nhưng form trên staging vẫn không nhúc nhích. Nguyên nhân gần như luôn nằm ở Bước 4 bên dưới — token bị nhét vào field ẩn g-recaptcha-response trong khi trang thực ra đang chờ một hàm callback cụ thể được gọi bằng tay.

Bước 1: Phát hiện reCAPTCHA Invisible

Trước khi gọi API, xác nhận đúng loại reCAPTCHA đang chạy trên trang. Tìm các mẫu sau trong HTML:

<!-- Option 1: div with data-size="invisible" -->
<div class="g-recaptcha" data-sitekey="6LdKlZEU..." data-size="invisible" data-callback="onSubmit"></div>

<!-- Option 2: button with data-sitekey (invisible by default) -->
<button data-sitekey="6LdKlZEU..." data-callback="onSubmit">Submit</button>

<!-- Option 3: programmatic execution -->
<script>
  grecaptcha.execute('6LdKlZEU...', {action: 'submit'});
</script>

Thấy data-size="invisible", một nút có data-sitekey mà không kèm checkbox hiển thị, hoặc lệnh gọi grecaptcha.execute() không nằm trong vùng chứa cố định — cả ba đều là dấu hiệu của reCAPTCHA Invisible.

Bước 2: Gửi task tới CaptchaAI

Gửi request tới in.php với tham số invisible: 1 — thiếu tham số này, CaptchaAI xử lý task như v2 tiêu chuẩn và token có thể bị site từ chối.

import requests

response = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY",
    "method": "userrecaptcha",
    "googlekey": "6LdKlZEUAAAAAPoxm...",
    "pageurl": "https://example.com/signup",
    "invisible": 1,
    "json": 1
})

task_id = response.json()["request"]
const params = new URLSearchParams({
  key: "YOUR_API_KEY", method: "userrecaptcha",
  googlekey: "6LdKlZEUAAAAAPoxm...",
  pageurl: "https://example.com/signup",
  invisible: 1, json: 1,
});
const res = await fetch(`https://ocr.captchaai.com/in.php?${params}`);
const { request: taskId } = await res.json();

Nếu trang dùng bản Enterprise của Invisible, thêm cả enterprise: 1 vào cùng request.

Bước 3: Polling lấy token từ res.php

Gọi endpoint res.php mỗi 5 giây cho tới khi status trả về 1 hoặc bạn hết số lần thử:

import time

for _ in range(40):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": "YOUR_API_KEY", "action": "get", "id": task_id, "json": 1
    }).json()
    if result.get("status") == 1:
        token = result["request"]
        break
    if result.get("request") != "CAPCHA_NOT_READY":
        raise RuntimeError(f"Error: {result['request']}")

Bước 4: Đưa token vào qua callback

Đây là bước quyết định thành-bại. reCAPTCHA Invisible cần bạn gọi đúng hàm callback, không chỉ set giá trị một field ẩn:

# Selenium example
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://example.com/signup")

# Find the callback name
callback = driver.execute_script("""
    var el = document.querySelector('[data-callback]');
    if (el) return el.getAttribute('data-callback');
    var btn = document.querySelector('[data-sitekey]');
    if (btn) return btn.getAttribute('data-callback');
    return null;
""")

# Execute the callback with the token
if callback:
    driver.execute_script(f"window['{callback}']('{token}');")
else:
    # Fallback: fill hidden field and submit
    driver.execute_script(f"""
        document.getElementById('g-recaptcha-response').innerHTML = '{token}';
        document.querySelector('form').submit();
    """)
// Puppeteer example
await page.evaluate((token) => {
  const el = document.querySelector('[data-callback]') || document.querySelector('[data-sitekey]');
  const callbackName = el?.getAttribute('data-callback');

  if (callbackName && window[callbackName]) {
    window[callbackName](token);
  } else {
    document.getElementById('g-recaptcha-response').innerHTML = token;
    document.querySelector('form').submit();
  }
}, token);

Không tìm thấy data-callback trên cả widget lẫn nút bấm? Dùng nhánh fallback trong đoạn code trên: điền token vào field ẩn g-recaptcha-response rồi tự submit form.

Cách đưa token Khi nào dùng Rủi ro
Gọi hàm callback (window[callbackName](token)) Widget có data-callback — đa số site dùng cách này Sai tên callback thì trang không phản hồi
Điền field ẩn + submit thủ công Không tìm thấy callback nào Một số form cần thêm field bắt buộc khác trước khi submit

Gộp thành một hàm hoàn chỉnh

Ghép bốn bước trên vào một hàm duy nhất để tái sử dụng trong pipeline QA hoặc script scraping của bạn:

import requests
import time

def solve_invisible_recaptcha(api_key, sitekey, page_url):
    submit = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": api_key, "method": "userrecaptcha", "googlekey": sitekey,
        "pageurl": page_url, "invisible": 1, "json": 1
    }).json()

    if submit.get("status") != 1:
        raise RuntimeError(f"Submit error: {submit.get('request')}")

    task_id = submit["request"]

    for _ in range(40):
        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:
            return result["request"]
        if result.get("request") != "CAPCHA_NOT_READY":
            raise RuntimeError(f"Solve error: {result.get('request')}")

    raise TimeoutError("Timed out")

token = solve_invisible_recaptcha("YOUR_API_KEY", "6LdKlZEU...", "https://example.com/signup")

Ví dụ chạy được đầy đủ

Cần một project mẫu đầy đủ hơn đoạn code ở trên? Repo mẫu trên GitHub có sẵn:

  • Thiết lập môi trường (.env, dependencies) cho từng ngôn ngữ
  • Vòng lặp polling kèm giới hạn số lần thử
  • Retry và backoff khi request lỗi
  • Xử lý lỗi cho từng mã lỗi CaptchaAI trả về

Xem ví dụ chạy được đầy đủ trên GitHub →


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

Những câu hỏi dev hay hỏi nhất khi tích hợp reCAPTCHA Invisible với CaptchaAI:

Làm sao biết reCAPTCHA trên trang là Invisible?

Tìm data-size="invisible" trên div widget, hoặc một nút có data-sitekey nhưng không có checkbox nào hiển thị. Không thấy ô kiểm trên trang gần như chắc chắn đó là reCAPTCHA Invisible.

reCAPTCHA Invisible khác reCAPTCHA v2 checkbox ở điểm nào?

Hai điểm khác biệt chính:

  • Phía API: giống hệt nhau — cùng endpoint, cùng tham số, chỉ thêm invisible: 1.
  • Phía trình duyệt: v2 checkbox đợi người dùng tick vào ô rồi tự động chèn token vào field ẩn; Invisible tự kích hoạt khi submit và cần bạn gọi đúng hàm callback JavaScript để đưa token vào.

Có bắt buộc phải thêm invisible=1 không?

Có. Thiếu tham số này, CaptchaAI xử lý task như v2 tiêu chuẩn và token có thể bị site từ chối vì sai loại challenge.

Polling res.php mất bao lâu để có token?

reCAPTCHA Invisible thường trả token trong dưới 30 giây, với tỷ lệ giải thành công cao:

  • Vòng lặp polling trong ví dụ trên thử tối đa 40 lần, mỗi lần cách nhau 5 giây.
  • Tổng thời gian chờ tối đa khoảng 200 giây trước khi báo timeout — đủ dư cho gần hết trường hợp thực tế.

reCAPTCHA Invisible có tính thêm phí hay cần thread riêng không?

Không, vì hai lý do:

  • CaptchaAI tính phí theo thread chứ không theo loại CAPTCHA, nên Invisible dùng chung hạn mức thread với các loại reCAPTCHA khác trong plan bạn đang có.
  • Gói BASIC ($15/tháng, 5 thread) đã đủ để test hoặc chạy khối lượng nhỏ; không cần nâng cấp riêng cho Invisible.

Bắt đầu giải reCAPTCHA Invisible bằng API CaptchaAI

Lấy API key tại captchaai.com/api.php. Thêm invisible=1 vào code giải v2 sẵn có.

Rồi áp dụng mẫu inject callback ở Bước 4 và chạy thử trên staging trước khi đưa vào pipeline chính.


Hướng dẫn liên quan

Đọc thêm để xử lý các tình huống liên quan tới reCAPTCHA v2 và Invisible:

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