Tích Hợp

Octoparse + CaptchaAI: Quét trực quan bằng cách xử lý CAPTCHA

Octoparse dừng thu thập ngay khi trang bật reCAPTCHA v2 hay Cloudflare Challenge — đó là giới hạn cố hữu của mọi công cụ scraping trực quan. Cách xử lý gọn nhất: để CaptchaAI giải CAPTCHA trong một script Python nhỏ, xuất cookie phiên đã đăng nhập, rồi nạp cookie đó vào Octoparse để job chạy tiếp như bình thường.

Bài viết trình bày hai hướng ghép CaptchaAI với Octoparse, kèm code Python chạy được ngay:

  1. Giải trước rồi nạp cookie — hợp với luồng no-code, chỉ giải một lần cho form đăng nhập.
  2. Gọi CaptchaAI trong script — hợp khi CAPTCHA xuất hiện rải rác trên nhiều trang.

Vì sao Octoparse dừng lại khi gặp CAPTCHA

Octoparse chạy theo nguyên tắc "chỉ và bấm": bạn dựng luồng trực quan, công cụ mô phỏng thao tác trình duyệt. Nhưng khi trang chèn CAPTCHA vào giữa luồng, Octoparse không có sẵn cơ chế giải nên job kẹt tại chỗ. Bốn tình huống hay gặp nhất:

Tình huống Điều xảy ra
reCAPTCHA v2 trên trang đích Octoparse dừng, phải giải thủ công
Cloudflare Challenge Trang tải nhưng không lấy được dữ liệu
CAPTCHA do giới hạn tần suất Sau N trang, CAPTCHA bật lên giữa chừng
Dữ liệu sau đăng nhập Form đăng nhập có gắn CAPTCHA

Điểm chung: bạn cần một token hợp lệ (với reCAPTCHA v2 là g-recaptcha-response) để trang chấp nhận request. CaptchaAI sinh token đó qua API, còn Octoparse lo phần trích xuất — hai công cụ chia việc rõ ràng.


Vì Octoparse là công cụ trực quan, cách ghép tự nhiên nhất là dùng một script Python làm "trợ lý": nó đăng nhập vào trang bạn có quyền truy cập, nhờ CaptchaAI giải CAPTCHA trong form đăng nhập, rồi xuất cookie phiên ra file để Octoparse nạp lại. Sau bước này, job Octoparse chạy dưới phiên đã xác thực và không còn chạm vào CAPTCHA nữa.

Script helper làm đúng bốn việc, theo thứ tự:

  1. Mở trang đăng nhập để lấy cookie ban đầu.
  2. Gửi task reCAPTCHA v2 tới CaptchaAI và chờ token trả về.
  3. Gửi form đăng nhập kèm token vừa nhận được.
  4. Xuất cookie phiên đã xác thực ra file cookies.json.
import requests
import time
import json

class OctoparseCaptchaHelper:
    """Solve CAPTCHAs and export cookies for Octoparse."""

    def __init__(self, api_key):
        self.api_key = api_key
        self.session = requests.Session()

    def solve_and_get_cookies(self, login_url, sitekey, credentials):
        """
        Solve login CAPTCHA and return session cookies.

        Steps:

        1. Visit login page to get initial cookies
        2. Solve CAPTCHA via CaptchaAI
        3. Submit login form with token
        4. Export authenticated cookies
        """
        # Step 1: Get initial cookies
        self.session.get(login_url, timeout=15)

        # Step 2: Solve CAPTCHA
        token = self._solve_recaptcha(sitekey, login_url)

        # Step 3: Submit login
        login_data = {
            **credentials,
            "g-recaptcha-response": token,
        }
        resp = self.session.post(login_url, data=login_data, timeout=30)

        if resp.status_code != 200:
            raise RuntimeError(f"Login failed: {resp.status_code}")

        # Step 4: Export cookies
        cookies = []
        for cookie in self.session.cookies:
            cookies.append({
                "name": cookie.name,
                "value": cookie.value,
                "domain": cookie.domain,
                "path": cookie.path,
            })

        return cookies

    def export_cookies_for_octoparse(self, cookies, output_file="cookies.json"):
        """Save cookies in format importable by Octoparse."""
        with open(output_file, "w") as f:
            json.dump(cookies, f, indent=2)
        print(f"Cookies saved to {output_file}")
        print(f"Import these in Octoparse: Task → Advanced Settings → Cookies")

    def _solve_recaptcha(self, sitekey, pageurl):
        """Solve reCAPTCHA via CaptchaAI."""
        resp = requests.post("https://ocr.captchaai.com/in.php", data={
            "key": self.api_key,
            "method": "userrecaptcha",
            "googlekey": sitekey,
            "pageurl": pageurl,
            "json": 1,
        }, timeout=30)
        result = resp.json()

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

        task_id = result["request"]
        time.sleep(15)

        for _ in range(24):
            resp = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": self.api_key, "action": "get",
                "id": task_id, "json": 1,
            }, timeout=15)
            data = resp.json()

            if data.get("status") == 1:
                return data["request"]
            if data["request"] != "CAPCHA_NOT_READY":
                raise RuntimeError(data["request"])
            time.sleep(5)

        raise TimeoutError("Solve timeout")

# Usage
helper = OctoparseCaptchaHelper("YOUR_API_KEY")

cookies = helper.solve_and_get_cookies(
    login_url="https://staging.example.com/qa-login",
    sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
    credentials={"username": "user", "password": "pass"},
)

helper.export_cookies_for_octoparse(cookies)

Bên trong _solve_recaptcha là bốn bước quen thuộc của CaptchaAI: gửi task tới in.php với method=userrecaptcha, nhận ID task, polling res.php tới khi có kết quả, rồi dùng token. Chạy xong, mở cookies.json và nhập vào Octoparse theo Task → Advanced Settings → Cookies.


Cách 2: giải CAPTCHA ngay trong script Python

Khi bạn cần kiểm soát chặt hơn — mỗi trang một sitekey, hoặc muốn tự quyết định thời điểm giải — hãy gọi CaptchaAI trực tiếp trong vòng lặp trích xuất thay vì phụ thuộc vào cookie giải sẵn. Cách này hợp với các site bật CAPTCHA thường xuyên, nơi một cookie duy nhất không đủ để chạy hết cả job.

def extract_with_captcha(api_key, urls, sitekey):
    """Extract data from CAPTCHA-protected pages."""
    results = []

    for url in urls:
        print(f"Processing: {url}")

        # Solve CAPTCHA for this page
        helper = OctoparseCaptchaHelper(api_key)
        token = helper._solve_recaptcha(sitekey, url)

        # Access page with token
        resp = requests.post(url, data={
            "g-recaptcha-response": token,
        }, timeout=30)

        # Parse response
        if resp.status_code == 200:
            results.append({
                "url": url,
                "content_length": len(resp.text),
                "status": "success",
            })
        else:
            results.append({
                "url": url,
                "status": f"failed ({resp.status_code})",
            })

        time.sleep(3)  # Rate limit

    return results

Dòng time.sleep(3) cuối vòng lặp giúp giãn đều request, tránh tự đẩy mình vào giới hạn tần suất của trang. Cần quét nhiều URL thì tăng số thread trên gói CaptchaAI để chạy song song, thay vì rút ngắn khoảng nghỉ.

Cách 2 phù hợp khi:

  • CAPTCHA bật lên rải rác trên nhiều trang khác nhau.
  • Mỗi trang có sitekey riêng cần xử lý.
  • Bạn muốn ghi log kết quả từng URL để dễ gỡ lỗi.

Chọn cách nào cho dự án của bạn

Chọn nhanh theo tình huống:

  • Dữ liệu nằm sau một lần đăng nhập, phần còn lại không có CAPTCHA → Cách 1: giải một lần, nạp cookie, để Octoparse chạy trực quan.
  • CAPTCHA bật lên rải rác trên nhiều trang, cần ghi log lỗi từng URL → Cách 2: giải đúng lúc, ngay trong script.

Đặt trong bối cảnh Việt Nam: một team agency ở TP.HCM theo dõi giá trên chính danh mục của mình ở Shopee, Lazada hay Tiki thường để marketing dựng luồng Octoparse trực quan, còn một dev duy trì script CaptchaAI cho phần đăng nhập và làm mới cookie. Cách chia việc này giữ được ưu điểm no-code mà vẫn xử lý được reCAPTCHA v2. Về chi phí, CaptchaAI tính theo thread (số CAPTCHA giải đồng thời), không theo lượt giải: gói BASIC ($15/tháng, 5 thread) đủ cho một job chạy định kỳ, và bạn nâng lên STANDARD ($30/tháng, 15 thread) khi cần nhiều luồng song song.

Một điểm cần rõ về năng lực: CaptchaAI giải reCAPTCHA v2/v3, Cloudflare Turnstile và Challenge, GeeTest v3, ảnh/OCR và lưới ảnh. CaptchaAI không giải hCaptcha hay FunCaptcha (Arkose Labs), nên nếu trang đích dùng các loại này thì cả hai cách trên đều không áp dụng được.


Cấu hình Octoparse cho trang có CAPTCHA

Thiết lập Khuyến nghị
Thời gian chờ tải trang Đặt trên 10 giây cho trang có CAPTCHA
Thử lại khi lỗi Bật, đặt 3 lần thử lại
Nhập cookie Dùng cookie đã xuất từ script helper
Chạy trên Cloud Dùng Octoparse Cloud với cookie giải sẵn
Chạy Local Dùng chế độ Local để giải CAPTCHA ban đầu

Với cookie giải sẵn, chế độ Cloud chạy ổn định nhất vì phiên đã xác thực từ trước. Chế độ Local hợp khi bạn muốn tự xử lý CAPTCHA lần đầu rồi mới giao luồng cho lịch chạy tự động.


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

CaptchaAI hỗ trợ những loại CAPTCHA nào cho Octoparse?

reCAPTCHA v2 và v3, Cloudflare Turnstile và Cloudflare Challenge, GeeTest v3, cùng CAPTCHA ảnh/OCR và lưới ảnh. Với luồng Octoparse phổ biến, loại bạn gặp nhất là reCAPTCHA v2 — dùng method=userrecaptcha như trong code ở trên. CaptchaAI không hỗ trợ hCaptcha và FunCaptcha.

Một lần chạy Octoparse tốn bao nhiêu tiền giải CAPTCHA?

CaptchaAI tính theo thread chứ không theo lượt giải, nên chi phí phụ thuộc số CAPTCHA bạn chạy song song, không phải tổng số lượt. Gói BASIC ($15/tháng, 5 thread) bao trọn một job định kỳ với số lượt giải không giới hạn trong tháng.

Nên chạy Octoparse ở chế độ Cloud hay Local khi có CAPTCHA?

Nếu đã giải trước và có cookie phiên, hãy chạy Cloud để job không bị gián đoạn. Chọn Local khi bạn cần can thiệp thủ công vào lần giải đầu tiên hoặc đang dựng và gỡ lỗi luồng.

Tùy thời gian sống của phiên trên trang đích. Đặt script helper chạy theo lịch (cron trên Linux/macOS hoặc Task Scheduler trên Windows) để làm mới cookies.json trước mỗi lần Octoparse trích xuất, tránh phiên hết hạn giữa chừng.


Hướng dẫn liên quan


Xử lý CAPTCHA trong luồng quét trực quan — dùng thử CaptchaAI.

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