Giải reCAPTCHA v2 qua API cần đúng bốn thao tác: trích xuất sitekey và pageurl, gửi tới bộ giải reCAPTCHA v2 của CaptchaAI qua in.php, polling res.php để lấy token, rồi chèn token vào form hoặc gọi callback của trang. Cả chu trình này thường xong trong dưới 60 giây.
Bài viết này dành cho dev cần một đoạn code chạy được ngay, không phải tổng quan lý thuyết. Nếu team QA hoặc automation đang test luồng đăng nhập, checkout hay gửi form có gắn reCAPTCHA v2, phần dưới có sẵn code Python, Node.js và bảng lỗi để tra khi request bị từ chối.
Chưa chắc trang đang dùng reCAPTCHA v2 hay bản khác? Xem trước cách nhận diện phiên bản reCAPTCHA — nhầm phiên bản là nguyên nhân phổ biến khiến request bị từ chối dù code không có lỗi gì.
Chuẩn bị trước khi giải reCAPTCHA v2 qua API
- API key CaptchaAI — lấy tại captchaai.com/api.php, chuỗi 32 ký tự.
- URL đầy đủ của trang — đúng URL nơi widget reCAPTCHA v2 được load, kèm scheme
https://. - sitekey — khóa công khai gắn với widget trên trang đó.
- HTTP client —
requests(Python),axios/fetch(Node.js), hoặccurl, dùng cái nào cũng được. - Thread còn khả dụng — tài khoản CaptchaAI cần còn thread trống trong gói đang dùng.
Bước 1: lấy sitekey và pageurl reCAPTCHA v2
Hai input bắt buộc là sitekey và pageurl. Sai một trong hai là lý do phổ biến nhất khiến submit thất bại, kể cả khi phần code còn lại không có lỗi gì. Nếu cặp giá trị này sai, CaptchaAI trả về ERROR_BAD_TOKEN_OR_PAGEURL — kiểm tra lại trước khi debug bất cứ điều gì khác.
pageurl là URL đầy đủ, kèm https://, đúng trang nơi widget hiển thị. Nếu widget nằm trong iframe ở subdomain khác, dùng URL của iframe đó thay vì URL trang cha.
Cách 1: thuộc tính data-sitekey trong HTML
Tìm thẻ chứa widget:
<div class="g-recaptcha" data-sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"></div>
Cách 2: tham số k= trong URL iframe
Iframe reCAPTCHA có dạng https://www.google.com/recaptcha/api2/anchor?ar=1&k=6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-&... — giá trị sau k= chính là sitekey.
Cách 3: network tab
Mở DevTools → Network, lọc theo từ khóa recaptcha; tham số k xuất hiện ở gần như mọi request liên quan.
Bước 2: gửi task tới in.php
Gửi sitekey, pageurl và API key tới in.php với method=userrecaptcha. CaptchaAI trả về một task_id để dùng ở bước polling tiếp theo:
import requests
API_KEY = "YOUR_API_KEY"
SITEKEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
PAGEURL = "https://staging.example.com/qa-login"
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": SITEKEY,
"pageurl": PAGEURL,
"json": 1,
}).json()
assert submit["status"] == 1, submit
task_id = submit["request"]
print("task id:", task_id)
Bản Node.js tương đương:
const r = await fetch("https://ocr.captchaai.com/in.php", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
key: API_KEY,
method: "userrecaptcha",
googlekey: SITEKEY,
pageurl: PAGEURL,
json: "1",
}),
});
const { status, request: taskId } = await r.json();
if (status !== 1) throw new Error(taskId);
reCAPTCHA invisible? Thêm
invisible=1vào request. Chi tiết tại cách hoạt động của reCAPTCHA invisible.
Bước 3: polling res.php để lấy token
reCAPTCHA v2 thường mất 15–60 giây để giải. Đợi 20 giây rồi mới polling, sau đó lặp lại mỗi 5 giây cho tới khi có kết quả:
import time
time.sleep(20)
while True:
res = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if res.get("request") == "CAPCHA_NOT_READY":
time.sleep(5)
continue
if res.get("status") == 1:
token = res["request"]
print("token:", token[:60], "…")
break
raise RuntimeError(res)
Token trả về là chuỗi dài, thường bắt đầu bằng 03AGdBq25.... Đừng cache token để dùng sau — nó có hạn dùng ngắn, xem phần lỗi thường gặp bên dưới.
Bước 4: chèn token reCAPTCHA v2 vào form
Cách chèn token phụ thuộc vào cách site xử lý reCAPTCHA.
Điền trực tiếp vào textarea
Phổ biến nhất là điền vào textarea g-recaptcha-response rồi submit form:
document.querySelector('textarea[name="g-recaptcha-response"]').value = token;
document.querySelector("form").submit();
Với Selenium:
driver.execute_script(
"document.querySelector('[name=\"g-recaptcha-response\"]').value = arguments[0];",
token,
)
driver.find_element(By.CSS_SELECTOR, "form").submit()
Với Playwright:
await page.evaluate((t) => {
document.querySelector('[name="g-recaptcha-response"]').value = t;
}, token);
await page.click('button[type="submit"]');
Gọi callback nếu widget có data-callback
Nhiều form dùng callback để kích hoạt submit chứ không đọc lại giá trị textarea — gọi thẳng hàm đó thay vì chỉ điền textarea:
const callback = document.querySelector(".g-recaptcha").dataset.callback;
if (callback && window[callback]) window[callback](token);
Lỗi thường gặp khi giải reCAPTCHA v2 qua API
| Lỗi | Nguyên nhân | Cách xử lý |
|---|---|---|
ERROR_GOOGLEKEY |
sitekey rỗng hoặc sai | Trích xuất lại sitekey từ trang hiện tại, không dùng giá trị cũ |
ERROR_PAGEURL |
Thiếu pageurl |
Gửi URL đầy đủ kèm scheme https:// |
ERROR_ZERO_BALANCE |
Hết thread khả dụng | Đợi thread giải phóng hoặc nâng gói |
ERROR_CAPTCHA_UNSOLVABLE |
Site siết challenge chặt hơn bình thường | Thử lại sau vài giây; xem các lỗi giải reCAPTCHA v2 thường gặp |
| Site từ chối token dù request thành công | Token đã hết hạn | Dùng token trong vòng khoảng 110 giây sau khi nhận, đừng để trễ |
Có token nhưng form vẫn không qua? Ba nguyên nhân hay gặp:
- Form dùng handler riêng thay vì đọc textarea — tìm
data-callbackvà gọi thẳng hàm đó. - Trang cần giữ cùng fingerprint như lúc lấy token — gửi kèm cookie và
User-Agentgiống với lúc submitsitekey/pageurl. - reCAPTCHA phụ thuộc IP — thêm
proxy(định dạnglogin:password@IP:PORT) vàproxytypevào request submit để bộ giải dùng đúng pool IP của bạn.
Ví dụ thực tế: test luồng checkout có reCAPTCHA v2
Một tình huống điển hình: team QA thuê ngoài chạy regression test hằng ngày cho luồng checkout của một sàn thương mại điện tử trên môi trường staging, trước mỗi lần release. Trang checkout gắn reCAPTCHA v2 checkbox, nên automation sẽ treo đúng ở bước này nếu không giải qua API.
Với gói STANDARD ($30/tháng, 15 thread), team chạy song song 15 luồng test — mỗi luồng gửi task riêng tới in.php, polling res.php độc lập, không phải xếp hàng chờ nhau. Cách làm giống hệt code Python bên dưới, chỉ khác PAGEURL trỏ vào domain staging nội bộ.
Code mẫu đầy đủ (Python)
import time
import requests
API_KEY = "YOUR_API_KEY"
SITEKEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
PAGEURL = "https://staging.example.com/qa-login"
def solve_recaptcha_v2():
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY, "method": "userrecaptcha",
"googlekey": SITEKEY, "pageurl": PAGEURL, "json": 1,
}).json()
if submit["status"] != 1:
raise RuntimeError(submit)
task_id = submit["request"]
time.sleep(20)
for _ in range(40):
res = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1,
}).json()
if res.get("request") == "CAPCHA_NOT_READY":
time.sleep(5)
continue
if res.get("status") == 1:
return res["request"]
raise RuntimeError(res)
raise TimeoutError("solve timed out")
if __name__ == "__main__":
token = solve_recaptcha_v2()
print("token:", token[:80])
Câu hỏi thường gặp
reCAPTCHA v2 khác reCAPTCHA v3 thế nào khi tích hợp API?
v2 hiển thị checkbox hoặc challenge ảnh mà người dùng phải tương tác trực tiếp; v3 chạy ẩn hoàn toàn và trả về điểm rủi ro thay vì yêu cầu click. Quy trình gọi CaptchaAI giống nhau cho cả hai, chỉ khác cách trang xử lý kết quả trả về.
Token reCAPTCHA v2 hết hạn sau bao lâu?
Khoảng 110 giây kể từ lúc CaptchaAI trả token. Submit trễ hơn mốc này, site sẽ từ chối token dù giá trị đúng — gửi form ngay sau khi nhận.
CaptchaAI có hỗ trợ hCaptcha hoặc FunCaptcha không?
Chưa. CaptchaAI hiện giải reCAPTCHA v2/v3, Cloudflare Turnstile, Cloudflare Challenge, GeeTest v3, CAPTCHA ảnh/OCR, grid image và BLS CAPTCHA. hCaptcha và FunCaptcha (Arkose Labs) chưa được hỗ trợ.
Giải reCAPTCHA v2 khối lượng lớn thì nên chọn gói nào?
Tuỳ số luồng chạy đồng thời, không phải tổng số CAPTCHA mỗi ngày — CaptchaAI tính theo thread, mỗi thread giải không giới hạn số lượt trong tháng. Vài luồng test dùng BASIC ($15/tháng, 5 thread) là đủ; workload nhiều luồng song song hơn thì cân nhắc STANDARD ($30/tháng, 15 thread) hoặc ADVANCE ($90/tháng, 50 thread).
Có thể chạy nhiều request reCAPTCHA v2 song song không?
Có, miễn tài khoản còn thread trống. Mỗi request gửi tới in.php chiếm một thread tới khi có kết quả; số luồng song song tối đa phụ thuộc gói đang dùng.