Phân Tích Kỹ Thuật

Hướng dẫn sử dụng cookie Cloudflare Challenge qa_session_cookie

Job scraping đang chạy ổn, rồi đột nhiên mọi request trả về 403 kèm trang trung gian Cloudflare. Thứ bạn thiếu là cookie phiên qa_session_cookie mà Cloudflare chỉ cấp sau khi trang thử thách được giải.

Bài viết chỉ rõ cookie đó ràng buộc theo gì, vì sao nó bị từ chối khi đổi IP hay User-Agent, và cách lấy token bằng API CaptchaAI — kèm code Python, Node.js.

Cloudflare đặt cookie này khi trang thử thách xác nhận request hợp lệ. Có cookie, request sau đi thẳng vào trang gốc; mất cookie là về vạch xuất phát.

Thuộc tính Chi tiết
Tên qa_session_cookie
Phạm vi Trang mục tiêu (.example.com), path /
Thời gian sống 30 phút – 24 giờ
Cờ HttpOnly, Secure (HTTPS), SameSite=None

Cookie còn bị ràng buộc theo ngữ cảnh phiên đã giải:

  • Địa chỉ IP — dùng từ IP khác gần như luôn hỏng.
  • User-Agent — phải trùng chuỗi UA lúc giải.
  • TLS fingerprint — vài cấu hình còn khớp cả TLS ClientHello.
  1. Client gọi trang nằm sau Cloudflare.
  2. Cloudflare chấm điểm rủi ro: IP, header, TLS fingerprint.
  3. Nếu bị gắn cờ, phản hồi là 403 hoặc 503 kèm trang thử thách JS.
  4. Trang thử thách kiểm tra trình duyệt, có thể hiện widget Turnstile.
  5. Giải xong, Cloudflare đặt qa_session_cookie rồi redirect về URL gốc.
  6. Request sau mang cookie đi qua, không gặp thử thách.

Chỉ bước 4 cần solver; phần còn lại là HTTP thường.

Ba cấp thử thách và cấp nào cần solver

Cấp thử thách Mã phản hồi Cần tương tác Mô tả
JS Challenge 503 Không Chỉ chạy JavaScript
Managed Challenge 403 Có thể Tự quyết: hiện Turnstile hoặc cho qua
Interactive Challenge 403 Luôn hiện widget Turnstile

CaptchaAI xử lý cả ba cấp bằng solver Cloudflare Challenge.

Lấy token Cloudflare Challenge bằng API CaptchaAI

Hai request: gửi task tới in.php, polling res.php tới khi có token. Thay YOUR_API_KEY bằng API key của bạn.

Python

import requests
import time

API_KEY = "YOUR_API_KEY"
TARGET_URL = "https://example.com/protected-page"

# Submit Cloudflare Challenge task
resp = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "turnstile",
    "sitekey": "0x0000000000000000000000",  # may be generic for CF challenge
    "pageurl": TARGET_URL,
    "json": "1",
}).json()

if resp["status"] != 1:
    raise Exception(f"Submit error: {resp['request']}")

task_id = resp["request"]
print(f"Task ID: {task_id}")

# Poll for result
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, "json": "1"
    }).json()

    if result["status"] == 1:
        token = result["request"]
        print(f"Token received: {token[:50]}...")
        break
    if result["request"] != "CAPCHA_NOT_READY":
        raise Exception(f"Error: {result['request']}")

Node.js

const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const TARGET_URL = 'https://example.com/protected-page';

const submit = await axios.post('https://ocr.captchaai.com/in.php', null, {
  params: {
    key: API_KEY,
    method: 'turnstile',
    sitekey: '0x0000000000000000000000',
    pageurl: TARGET_URL,
    json: 1,
  }
});
const taskId = submit.data.request;

// Poll
let token = null;
for (let i = 0; i < 30; 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: taskId, json: 1 }
  });
  if (poll.data.status === 1) {
    token = poll.data.request;
    break;
  }
}
console.log(`Token: ${token.substring(0, 50)}...`);

Token chỉ có giá trị khi nằm đúng field cf-turnstile-response và form được submit. Ví dụ dùng Selenium trên staging của bạn.

# With Selenium
from selenium import webdriver

driver = webdriver.Chrome()
driver.get(TARGET_URL)  # Load the challenge page

# Inject token into Turnstile response field
driver.execute_script("""
    const input = document.querySelector('input[name="cf-turnstile-response"]');
    if (input) input.value = arguments[0];

    // Trigger form submit or callback
    const form = document.querySelector('form');
    if (form) form.submit();
""", token)

# Wait for redirect and extract cookies
import time
time.sleep(3)
cookies = driver.get_cookies()
qa_session_cookie = next(
    (c for c in cookies if c['name'] == 'qa_session_cookie'), None
)
if qa_session_cookie:
    print(f"qa_session_cookie: {qa_session_cookie['value'][:30]}...")

Có cookie rồi thì bỏ trình duyệt: gắn vào requests.Session(), giữ nguyên User-Agent lúc giải.

session = requests.Session()
session.cookies.set("qa_session_cookie", qa_session_cookie["value"], domain=".example.com")
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})

# Now access protected pages
resp = session.get("https://example.com/api/data")
print(resp.status_code)  # 200

Cookie sẽ hết hạn. Đọc trường expiry trước mỗi lần dùng thay vì chờ 403 mới xử lý.

import datetime

def is_cookie_valid(cookie):
    if not cookie:
        return False
    expiry = cookie.get("expiry", 0)
    return datetime.datetime.now().timestamp() < expiry - 60  # 60s buffer

def get_or_refresh_clearance(driver, target_url, solve_func):
    cookies = driver.get_cookies()
    cf = next((c for c in cookies if c["name"] == "qa_session_cookie"), None)
    if is_cookie_valid(cf):
        return cf["value"]

    # Re-solve
    token = solve_func(target_url)
    # ... inject and extract new cookie

Biên 60 giây đủ để cookie không hết hạn giữa chừng.

Ví dụ: đội QA giám sát giá thương mại điện tử

Một team ở TP.HCM theo dõi giá công khai trên Shopee, Lazada và Tiki cho chính danh mục của công ty. Mỗi domain chỉ cần một phiên đã giải; hàng nghìn request sau dùng chung cookie.

  • Một worker giữ một phiên: một cookie, một IP, một User-Agent.
  • Ghi log lúc giải và hạn cookie để soi khi 403 tăng.
  • Tối giản dữ liệu lưu lại theo tinh thần Nghị định 13/2023/NĐ-CP.

Ở khối lượng này, BASIC ($15/tháng, 5 thread) đã đủ: CaptchaAI tính theo thread (luồng giải đồng thời), không theo số lần giải.

Lỗi thường gặp và cách xử lý

Vấn đề Nguyên nhân Cách xử lý
Cookie bị từ chối sau khi giải IP không khớp Dùng cùng proxy khi giải và khi request
Cookie hết hạn quá nhanh TTL site đặt ngắn Giải lại trước hạn theo expiry
Vẫn 403 dù cookie còn hạn User-Agent không khớp Đồng bộ UA giữa hai phiên
Trang thử thách không tải JavaScript bị tắt Dùng trình duyệt thật (Selenium, Puppeteer)

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

Gần như luôn do IP hoặc User-Agent lệch giữa lúc giải và lúc request.

CaptchaAI có giải hCaptcha trên trang thử thách không?

Không. CaptchaAI hỗ trợ Cloudflare Challenge, Turnstile, reCAPTCHA v2/v3, GeeTest v3 và CAPTCHA ảnh; hCaptcha và FunCaptcha chưa được hỗ trợ.

Nên giải lại theo lịch hay đợi gặp 403?

Giải lại theo expiry rẻ hơn: tránh được request hỏng và chuỗi retry theo sau. Cookie sống theo thời hạn chứ không theo số lần dùng — một phiên 30 phút thường đủ cho hàng nghìn request.

Giải trang Cloudflare Challenge với CaptchaAI

Lấy API key tại captchaai.com rồi chạy ví dụ Python trong bài trên staging của bạn.

Hướng dẫn liên quan

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