Trường Hợp Sử Dụng

Tập lệnh tự động hóa CAPTCHA với CaptchaAI

Bạn cần giải reCAPTCHA v2, Cloudflare Turnstile hoặc CAPTCHA hình ảnh trong pipeline test mà không muốn viết lại logic gửi task và polling từ đầu? Dưới đây là sáu tập lệnh Python và Node.js dùng được ngay, mỗi tập lệnh gọi thẳng API của CaptchaAI và xử lý trọn luồng: gửi request tới in.php, polling res.php cho đến khi có kết quả, rồi trả token bạn dùng ngay trong form hoặc script test. Đội QA tại các công ty outsourcing ở TP.HCM hay Hà Nội thường ghép các tập lệnh này vào bộ test tự động để không phải dừng lại tay mỗi khi gặp CAPTCHA trên môi trường staging.

Vì sao nên dùng tập lệnh dựng sẵn thay vì gọi API thủ công

Gọi trực tiếp in.phpres.php bằng tay cho mỗi CAPTCHA khá tốn công: bạn phải tự nhớ tham số nào ứng với loại nào (googlekey cho reCAPTCHA, sitekey cho Turnstile), tự viết vòng lặp polling, và tự xử lý các trường hợp như CAPCHA_NOT_READY hay timeout. Các tập lệnh dưới đây gói toàn bộ luồng đó vào một hàm — gọi một lần, nhận token, dùng ngay. Bạn có thể copy nguyên file, đổi API_KEY, và chạy được luôn mà không cần đọc lại tài liệu API mỗi lần.

Bảng dưới đây giúp bạn chọn nhanh đúng tập lệnh cho từng loại CAPTCHA:

Tập lệnh Loại CAPTCHA Tham số method
Tập lệnh 1 reCAPTCHA v2 userrecaptcha
Tập lệnh 2 Cloudflare Turnstile turnstile
Tập lệnh 3 Hình ảnh (OCR) base64
Tập lệnh 4 Hàng loạt (nhiều task cùng lúc) userrecaptcha (đổi được)
Tập lệnh 5 Bất kỳ loại nào (Node.js) truyền động theo tham số

Tập lệnh 1: giải reCAPTCHA v2 bằng Python

Tập lệnh này gửi site_keypage_url tới in.php với method=userrecaptcha, in ra ID task, rồi polling res.php mỗi 5 giây cho tới khi nhận được token. Có giới hạn 60 lần polling (khoảng 5 phút) để tránh treo vô hạn nếu CAPTCHA không giải được.

#!/usr/bin/env python3
"""Solve reCAPTCHA v2 and print the token."""
import requests
import time
import sys

API_KEY = "YOUR_API_KEY"

def solve_recaptcha_v2(site_key, page_url):
    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": site_key,
        "pageurl": page_url
    })
    if not resp.text.startswith("OK|"):
        print(f"Error: {resp.text}", file=sys.stderr)
        sys.exit(1)

    task_id = resp.text.split("|")[1]
    print(f"Task ID: {task_id}")

    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
        })
        if result.text == "CAPCHA_NOT_READY":
            print(".", end="", flush=True)
            continue
        if result.text.startswith("OK|"):
            print()
            return result.text.split("|")[1]
        print(f"\nError: {result.text}", file=sys.stderr)
        sys.exit(1)

    print("\nTimeout", file=sys.stderr)
    sys.exit(1)

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print(f"Usage: {sys.argv[0]} <site_key> <page_url>")
        sys.exit(1)
    token = solve_recaptcha_v2(sys.argv[1], sys.argv[2])
    print(token)

Chạy thử:

python solve_recaptcha.py "6Le-wvkS..." "https://example.com/form"

Tập lệnh 2: giải Cloudflare Turnstile

Với Turnstile, tham số bắt buộc đổi thành sitekey thay vì googlekey, còn method đổi thành turnstile. Luồng gửi task và polling giữ nguyên như tập lệnh 1, chỉ khác cách báo lỗi — dùng exception thay vì thoát tiến trình.

#!/usr/bin/env python3
"""Solve Cloudflare Turnstile and print the token."""
import requests
import time

API_KEY = "YOUR_API_KEY"

def solve_turnstile(site_key, page_url):
    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY,
        "method": "turnstile",
        "sitekey": site_key,
        "pageurl": page_url
    })
    task_id = resp.text.split("|")[1]

    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
        })
        if result.text == "CAPCHA_NOT_READY": continue
        if result.text.startswith("OK|"): return result.text.split("|")[1]
        raise Exception(result.text)
    raise TimeoutError()

token = solve_turnstile("0x4AAAAA...", "https://example.com")
print(token)

Tập lệnh 3: giải CAPTCHA hình ảnh (OCR)

Tập lệnh này nhận ảnh CAPTCHA từ URL hoặc file cục bộ, encode sang base64 rồi gửi với method=base64. Vòng lặp polling ngắn hơn (30 lần, khoảng 2,5 phút) vì CAPTCHA hình ảnh thường được giải nhanh hơn CAPTCHA dạng token.

#!/usr/bin/env python3
"""Solve an image CAPTCHA from a file or URL."""
import requests
import base64
import time
import sys

API_KEY = "YOUR_API_KEY"

def solve_image(image_source):
    # Load image
    if image_source.startswith("http"):
        img_data = requests.get(image_source).content
    else:
        with open(image_source, "rb") as f:
            img_data = f.read()

    img_b64 = base64.b64encode(img_data).decode()

    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY,
        "method": "base64",
        "body": img_b64
    })
    task_id = resp.text.split("|")[1]

    for _ in range(30):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id
        })
        if result.text == "CAPCHA_NOT_READY": continue
        if result.text.startswith("OK|"): return result.text.split("|")[1]
        raise Exception(result.text)
    raise TimeoutError()

if __name__ == "__main__":
    text = solve_image(sys.argv[1])
    print(text)

Chạy thử:

python solve_image.py captcha.png
python solve_image.py "https://example.com/captcha.jpg"

Tập lệnh 4: giải CAPTCHA hàng loạt với ThreadPoolExecutor

Khi cần giải nhiều CAPTCHA cùng lúc — ví dụ kiểm thử nhiều trang staging trong một lượt CI — tập lệnh này dùng ThreadPoolExecutor để gửi nhiều request song song thay vì xử lý tuần tự từng cái. Mỗi kết quả trả về kèm trạng thái ok hoặc failed, nên bạn biết chính xác task nào cần thử lại.

#!/usr/bin/env python3
"""Solve multiple CAPTCHAs concurrently."""
import requests
import time
from concurrent.futures import ThreadPoolExecutor, as_completed

API_KEY = "YOUR_API_KEY"

def solve_one(site_key, page_url):
    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY, "method": "userrecaptcha",
        "googlekey": site_key, "pageurl": page_url
    })
    task_id = resp.text.split("|")[1]

    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
        })
        if result.text == "CAPCHA_NOT_READY": continue
        if result.text.startswith("OK|"): return result.text.split("|")[1]
        raise Exception(result.text)
    raise TimeoutError()

def solve_batch(tasks, max_workers=5):
    """
    tasks: list of (site_key, page_url) tuples
    Returns: list of tokens
    """
    results = []
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = {
            executor.submit(solve_one, sk, url): (sk, url)
            for sk, url in tasks
        }
        for future in as_completed(futures):
            sk, url = futures[future]
            try:
                token = future.result()
                results.append({"url": url, "token": token, "status": "ok"})
            except Exception as e:
                results.append({"url": url, "error": str(e), "status": "failed"})
    return results

# Example
tasks = [
    ("6Le-wvkS...", "https://example.com/page1"),
    ("6Le-wvkS...", "https://example.com/page2"),
    ("6Le-wvkS...", "https://example.com/page3"),
]
results = solve_batch(tasks)
for r in results:
    print(f"{r['url']}: {r['status']}")

Tham số max_workers nên khớp với số thread khả dụng trong gói CaptchaAI của bạn — xem FAQ bên dưới để tránh gửi dư request.

Tập lệnh 5: bộ giải đa năng bằng Node.js

Bản Node.js này không cố định loại CAPTCHA — bạn truyền method và các tham số tương ứng (googlekey/sitekey) khi gọi hàm solve(), dùng chung một vòng lặp polling cho mọi loại. Phù hợp khi codebase của bạn cần gọi nhiều loại CAPTCHA từ cùng một module thay vì viết riêng từng hàm.

#!/usr/bin/env node
// Solve any CAPTCHA type from the command line
const axios = require("axios");

const API_KEY = "YOUR_API_KEY";

async function solve(params) {
  params.key = API_KEY;
  const submit = await axios.get("https://ocr.captchaai.com/in.php", {
    params,
  });
  if (!submit.data.startsWith("OK|")) throw new Error(submit.data);
  const taskId = submit.data.split("|")[1];

  while (true) {
    await new Promise((r) => setTimeout(r, 5000));
    const result = await axios.get("https://ocr.captchaai.com/res.php", {
      params: { key: API_KEY, action: "get", id: taskId },
    });
    if (result.data === "CAPCHA_NOT_READY") continue;
    if (result.data.startsWith("OK|")) return result.data.split("|")[1];
    throw new Error(result.data);
  }
}

// Usage examples:
// Solve reCAPTCHA v2
// solve({ method: "userrecaptcha", googlekey: "SITE_KEY", pageurl: "URL" })

// Solve Turnstile
// solve({ method: "turnstile", sitekey: "SITE_KEY", pageurl: "URL" })

module.exports = { solve };

Tập lệnh kiểm tra số dư tài khoản

Trước khi chạy hàng loạt, kiểm tra số dư bằng action=getbalance để chắc chắn tài khoản còn đủ cho lượt test tiếp theo.

#!/usr/bin/env python3
"""Check CaptchaAI account balance."""
import requests

API_KEY = "YOUR_API_KEY"

resp = requests.get("https://ocr.captchaai.com/res.php", params={
    "key": API_KEY,
    "action": "getbalance"
})
print(f"Balance: ${resp.text}")

Ví dụ thực tế: đội QA outsourcing ghép tập lệnh vào lượt kiểm thử đêm

Nhiều công ty outsourcing tại TP.HCM và Hà Nội vận hành đội QA phụ trách nhiều dự án e-commerce cùng lúc. Một tình huống phổ biến: script kiểm thử checkout cần đi qua Cloudflare Turnstile trên hàng chục trang staging mỗi đêm trước khi release. Thay vì gọi tập lệnh 2 tuần tự cho từng trang, đội QA ghép danh sách site_key/page_url của các môi trường staging vào tập lệnh 4 rồi chạy song song. Với gói STANDARD ($30/tháng, 15 thread), một lượt kiểm thử 15 trang có thể hoàn tất trong một vòng lặp duy nhất thay vì 15 vòng lặp riêng lẻ. Cách ghép tương tự cũng dùng được cho các đội theo dõi giá trên catalog của chính họ trên Shopee hoặc Tiki — dùng tập lệnh hàng loạt để xử lý nhiều CAPTCHA hình ảnh cùng lúc thay vì từng cái một.

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

Chi phí chạy các tập lệnh này ước tính thế nào?

CaptchaAI tính phí theo thread, không theo từng lần giải: BASIC ($15/tháng, 5 thread) cho tới ENTERPRISE ($300/tháng, 200 thread), mỗi thread giải không giới hạn số lần trong tháng. Dùng tập lệnh kiểm tra số dư ở trên để theo dõi mức tiêu thụ trong lúc test.

Có thể dùng các tập lệnh này trong production không?

Có. Thêm xử lý lỗi và ghi log đầy đủ trước khi đưa vào production — tập lệnh giải hàng loạt ở trên đã có sẵn xử lý lỗi theo từng task, các tập lệnh còn lại nên bổ sung tương tự.

Nên đặt max_workers bao nhiêu cho tập lệnh giải hàng loạt?

Đặt bằng đúng số thread khả dụng trong gói của bạn — ví dụ BASIC 5 thread thì đặt max_workers=5. Đặt cao hơn số thread được cấp không giúp giải nhanh hơn, chỉ tạo thêm request chờ.

Các tập lệnh cần cài thêm thư viện gì?

Bản Python cần requests (pip install requests); bản Node.js cần axios (npm install axios). Ngoài hai thư viện này, phần còn lại đều dùng thư viện chuẩn của ngôn ngữ (base64, time, concurrent.futures).

reCAPTCHA v2 và Turnstile khác nhau thế nào khi gọi API?

Chỉ khác tên tham số: method=userrecaptcha với googlekey cho reCAPTCHA v2, method=turnstile với sitekey cho Turnstile. Luồng gửi task, polling res.php và dùng token giống hệt nhau.

Hướng dẫn liên quan

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