Tài Liệu Tham Khảo

Chuyển từ AZCaptcha sang CaptchaAI: ánh xạ API và code mẫu

Nếu bạn đang dùng AZCaptcha, đổi sang CaptchaAI thường chỉ mất 15–30 phút cho một codebase: cả hai dùng chung định dạng API tương thích 2Captcha, nên phần lớn công việc chỉ là đổi base URL và API key.

Nhiều đội automation tại các công ty outsourcing ở TP.HCM, Hà Nội đang chạy AZCaptcha cho pipeline QA hay thu thập dữ liệu, và đổi provider giữa lúc production đang chạy là rủi ro thật — không ai muốn task giải CAPTCHA bị rớt giữa ca trực. Dưới đây là 4 bước cụ thể, kèm bảng ánh xạ endpoint/tham số và cách kiểm tra song song trước khi cắt traffic hẳn sang CaptchaAI.

Quy trình di chuyển 4 bước

Bước 1: Lấy API key CaptchaAI

  1. Đăng ký tại captchaai.com
  2. Nạp tiền vào tài khoản
  3. Sao chép API key từ dashboard

Bước 2: Cập nhật code — chỉ URL thay đổi

Logic gửi request và polling giữ nguyên hoàn toàn; đây là toàn bộ phần cần sửa cho reCAPTCHA v2 bằng Python và JavaScript.

Python — Trước khi đổi (AZCaptcha)

import requests

API_KEY = "your_azcaptcha_key"

def solve_recaptcha(sitekey, pageurl):
    # Submit
    resp = requests.post("https://azcaptcha.com/in.php", data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": pageurl,
        "json": 1
    })
    data = resp.json()
    if data["status"] != 1:
        return {"error": data["request"]}

    captcha_id = data["request"]

    # Poll
    import time
    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://azcaptcha.com/res.php", params={
            "key": API_KEY, "action": "get", "id": captcha_id, "json": 1
        }).json()
        if result["status"] == 1:
            return {"solution": result["request"]}
        if result["request"] != "CAPCHA_NOT_READY":
            return {"error": result["request"]}

    return {"error": "TIMEOUT"}

Python — Sau khi đổi (CaptchaAI)

import os
import time
import requests

API_KEY = os.environ["CAPTCHAAI_API_KEY"]  # Changed: use env var

def solve_recaptcha(sitekey, pageurl):
    # Submit — only URL changed
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": pageurl,
        "json": 1
    })
    data = resp.json()
    if data.get("status") != 1:
        return {"error": data.get("request")}

    captcha_id = data["request"]

    # Poll — only URL changed
    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": captcha_id, "json": 1
        }).json()
        if result.get("status") == 1:
            return {"solution": result["request"]}
        if result.get("request") != "CAPCHA_NOT_READY":
            return {"error": result.get("request")}

    return {"error": "TIMEOUT"}

JavaScript — Trước khi đổi (AZCaptcha)

const axios = require("axios");
const API_KEY = "your_azcaptcha_key";

async function solveRecaptcha(sitekey, pageurl) {
  const submit = await axios.post("https://azcaptcha.com/in.php", null, {
    params: { key: API_KEY, method: "userrecaptcha", googlekey: sitekey, pageurl, json: 1 },
  });
  if (submit.data.status !== 1) return { error: submit.data.request };

  const captchaId = submit.data.request;
  for (let i = 0; i < 60; i++) {
    await new Promise((r) => setTimeout(r, 5000));
    const poll = await axios.get("https://azcaptcha.com/res.php", {
      params: { key: API_KEY, action: "get", id: captchaId, json: 1 },
    });
    if (poll.data.status === 1) return { solution: poll.data.request };
    if (poll.data.request !== "CAPCHA_NOT_READY") return { error: poll.data.request };
  }
  return { error: "TIMEOUT" };
}

JavaScript — Sau khi đổi (CaptchaAI)

const axios = require("axios");
const API_KEY = process.env.CAPTCHAAI_API_KEY;  // Changed: env var

async function solveRecaptcha(sitekey, pageurl) {
  // Only URLs changed
  const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
    params: { key: API_KEY, method: "userrecaptcha", googlekey: sitekey, pageurl, json: 1 },
  });
  if (submit.data.status !== 1) return { error: submit.data.request };

  const captchaId = submit.data.request;
  for (let i = 0; i < 60; i++) {
    await new Promise((r) => setTimeout(r, 5000));
    const poll = await axios.get("https://ocr.captchaai.com/res.php", {
      params: { key: API_KEY, action: "get", id: captchaId, json: 1 },
    });
    if (poll.data.status === 1) return { solution: poll.data.request };
    if (poll.data.request !== "CAPCHA_NOT_READY") return { error: poll.data.request };
  }
  return { error: "TIMEOUT" };
}

Bước 3: Bọc provider vào một class dùng chung

import os
import time
import requests

class CaptchaProvider:
    def __init__(self, base_url, api_key):
        self.submit_url = f"{base_url}/in.php"
        self.result_url = f"{base_url}/res.php"
        self.api_key = api_key
        self.session = requests.Session()

    def solve(self, sitekey, pageurl, method="userrecaptcha"):
        resp = self.session.post(self.submit_url, data={
            "key": self.api_key,
            "method": method,
            "googlekey": sitekey,
            "pageurl": pageurl,
            "json": 1
        })
        data = resp.json()
        if data.get("status") != 1:
            return {"error": data.get("request")}

        captcha_id = data["request"]
        for _ in range(60):
            time.sleep(5)
            result = self.session.get(self.result_url, params={
                "key": self.api_key, "action": "get",
                "id": captcha_id, "json": 1
            }).json()
            if result.get("status") == 1:
                return {"solution": result["request"]}
            if result.get("request") != "CAPCHA_NOT_READY":
                return {"error": result.get("request")}
        return {"error": "TIMEOUT"}

# Switch by changing one line:
# provider = CaptchaProvider("https://azcaptcha.com", "old_key")
provider = CaptchaProvider(
    "https://ocr.captchaai.com",
    os.environ["CAPTCHAAI_API_KEY"]
)

Bước 4: Chạy song song trước khi cắt traffic

def parallel_test(sitekey, pageurl, runs=10):
    azcaptcha = CaptchaProvider("https://azcaptcha.com", "old_key")
    captchaai = CaptchaProvider(
        "https://ocr.captchaai.com",
        os.environ["CAPTCHAAI_API_KEY"]
    )

    results = {"azcaptcha": [], "captchaai": []}

    for i in range(runs):
        start = time.time()
        az_result = azcaptcha.solve(sitekey, pageurl)
        results["azcaptcha"].append({
            "success": "solution" in az_result,
            "time": time.time() - start
        })

        start = time.time()
        cai_result = captchaai.solve(sitekey, pageurl)
        results["captchaai"].append({
            "success": "solution" in cai_result,
            "time": time.time() - start
        })

    for provider, data in results.items():
        successes = sum(1 for r in data if r["success"])
        avg_time = sum(r["time"] for r in data) / len(data)
        print(f"{provider}: {successes}/{runs} success, {avg_time:.1f}s avg")

Đừng thu hồi key AZCaptcha ngay sau khi đổi xong. Giữ cả hai chạy song song ít nhất 24 giờ — đó là đường lùi nếu CaptchaAI gặp sự cố tạm thời ở khu vực bạn dùng.


So sánh endpoint: AZCaptcha và CaptchaAI

Chỉ phần host thay đổi, path và cấu trúc request giữ nguyên:

Hành động AZCaptcha CaptchaAI
Gửi nhiệm vụ https://azcaptcha.com/in.php https://ocr.captchaai.com/in.php
Nhận kết quả https://azcaptcha.com/res.php https://ocr.captchaai.com/res.php
Kiểm tra số dư res.php?action=getbalance res.php?action=getbalance
Báo cáo sai res.php?action=reportbad res.php?action=reportbad

Tham số nào giữ nguyên, tham số nào cần đổi

Chỉ key là bắt buộc phải đổi — phần còn lại giống hệt AZCaptcha:

Tham số AZCaptcha CaptchaAI Ghi chú
key API key API key Khóa khác — nhận tại captchaai.com
method userrecaptcha userrecaptcha Giống nhau
googlekey Site key Site key Giống nhau
pageurl URL trang URL trang Giống nhau
json 1 1 Giống nhau
proxy user:pass@host:port user:pass@host:port Cùng định dạng
proxytype HTTP/SOCKS5 HTTP/SOCKS5 Giống nhau

Checklist trước khi cắt traffic

  • [ ] Tạo tài khoản CaptchaAI và nạp tiền
  • [ ] Thay base URL trong toàn bộ codebase
  • [ ] Đổi API key sang biến môi trường
  • [ ] Chạy parallel_test() với 10+ lượt giải
  • [ ] So sánh tỷ lệ giải thành công
  • [ ] So sánh thời gian giải trung bình
  • [ ] Cập nhật monitoring/alerting cho endpoint mới
  • [ ] Chuyển traffic production sang CaptchaAI
  • [ ] Theo dõi 24 giờ trước khi thu hồi key AZCaptcha

Xử lý lỗi thường gặp khi chuyển đổi

Bốn tình huống hay gặp nhất sau khi đổi endpoint:

  • ERROR_KEY_DOES_NOT_EXIST — API key sai. Kiểm tra lại API key CaptchaAI từ dashboard.
  • ERROR_ZERO_BALANCE — Tài khoản mới chưa có tiền. Nạp tiền tại captchaai.com.
  • Mã lỗi khác nhau — Khác biệt nhỏ giữa hai bộ mã lỗi của hai nhà cung cấp. Lập bảng ánh xạ; phần lớn mã lỗi giống hệt nhau.
  • Tỷ lệ giải khác nhau — Hai bên dùng solver pool khác nhau. Chạy 50+ lượt test để so sánh có ý nghĩa thống kê.

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

Di chuyển từ AZCaptcha sang CaptchaAI mất bao lâu?

Khoảng 15–30 phút cho một codebase — chủ yếu là tìm-và-thay base URL, cộng thêm thời gian chạy kiểm tra song song để xác nhận ổn định trước khi cắt traffic thật.

Cấu hình proxy hiện tại có cần đổi không?

Không. CaptchaAI dùng đúng tham số proxyproxytype như AZCaptcha, nên logic proxy trong code hiện có giữ nguyên.

CaptchaAI tính phí theo mỗi lượt giải hay theo cách khác?

Khác AZCaptcha, CaptchaAI tính phí theo thread, không theo từng lượt giải. Gói nhỏ nhất là BASIC ($15/tháng, 5 thread) với số lượt giải không giới hạn mỗi thread — hợp với khối lượng CAPTCHA dao động thất thường trong tháng.

CaptchaAI có giải được loại CAPTCHA nào mà AZCaptcha không hỗ trợ không?

Có. Ngoài reCAPTCHA v2/v3, CaptchaAI còn giải Cloudflare Turnstile, Cloudflare Challenge, GeeTest v3, CAPTCHA ảnh/OCR, lưới ảnh, BLS, cùng CaptchaFox, Friendly Captcha và Lemin (beta). CaptchaAI hiện không hỗ trợ hCaptcha hoặc FunCaptcha (Arkose Labs).

Bắt đầu ngay

Lấy API key CaptchaAI của bạn, đổi base URL, và chạy parallel_test() để xác nhận ổn định trước khi cắt traffic hẳn.

Hướng dẫn liên quan:

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