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.
Cookie qa_session_cookie là gì
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.
Luồng thử thách: từ 403/503 đến lúc có cookie
- Client gọi trang nằm sau Cloudflare.
- Cloudflare chấm điểm rủi ro: IP, header, TLS fingerprint.
- Nếu bị gắn cờ, phản hồi là 403 hoặc 503 kèm trang thử thách JS.
- Trang thử thách kiểm tra trình duyệt, có thể hiện widget Turnstile.
- Giải xong, Cloudflare đặt
qa_session_cookierồi redirect về URL gốc. - 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 | Có | 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)}...`);
Đưa token vào trang thử thách để nhận cookie
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]}...")
Dùng lại cookie cho các request sau
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
Vòng đời cookie và thời điểm giải lại
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
Vì sao cookie bị từ chối dù vừa giải xong?
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.