Không phải tất cả CAPTCHA đều xuất hiện khi trang tải lần đầu tiên. Nhiều trang web hiển thị CAPTCHA một cách lười biếng — sau một lần nhấp nút, tiêu điểm biểu mẫu, cuộn hoặc hẹn giờ. Nếu tính năng tự động hóa của bạn lấy nguồn trang ngay lập tức thì CAPTCHA vẫn chưa có ở đó. Hướng dẫn này bao gồm cách phát hiện và chờ đợi CAPTCHA được tải động.
Trình kích hoạt tải chậm phổ biến
| Trình kích hoạt | Ví dụ | Cách kích hoạt |
|---|---|---|
| Bấm vào nút | "Gửi" thêm reCAPTCHA vào biểu mẫu | Bấm vào nút đầu tiên |
| Tiêu điểm của biểu mẫu | CAPTCHA xuất hiện khi tập trung vào dữ liệu nhập | Tập trung vào trường email/password |
| Vị trí cuộn | CAPTCHA tải khi phần này hiển thị | Di chuyển đến biểu mẫu |
| hẹn giờ | CAPTCHA tải sau 3 giây | Chờ sự chậm trễ |
| Điều kiện JavaScript | Tải CAPTCHA sau phản hồi AJAX | Kích hoạt yêu cầu tiên quyết |
Cách 1: MutationObserver
Xem DOM để biết các phần tử CAPTCHA đang được thêm vào:
Puppeteer
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://staging.example.com/qa-login');
// Set up MutationObserver before triggering the CAPTCHA
const captchaInfo = await page.evaluate(() => {
return new Promise((resolve) => {
// Check if already present
const existing = document.querySelector('.g-recaptcha, .cf-turnstile, .h-captcha');
if (existing) {
resolve({
type: existing.className,
sitekey: existing.getAttribute('data-sitekey'),
});
return;
}
// Watch for new elements
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.nodeType !== 1) continue;
const captcha = node.matches?.('.g-recaptcha, .cf-turnstile, .h-captcha')
? node
: node.querySelector?.('.g-recaptcha, .cf-turnstile, .h-captcha');
if (captcha) {
observer.disconnect();
resolve({
type: captcha.className,
sitekey: captcha.getAttribute('data-sitekey'),
});
return;
}
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
// Timeout after 30 seconds
setTimeout(() => {
observer.disconnect();
resolve(null);
}, 30000);
});
});
console.log('Detected CAPTCHA:', captchaInfo);
Kích hoạt tải
// Click the submit button to trigger CAPTCHA
await page.click('#submit-btn');
// Or focus the input
await page.focus('#email');
// Or scroll to the form
await page.evaluate(() => {
document.querySelector('#signup-form').scrollIntoView();
});
Phương pháp 2: Chờ chèn tập lệnh
CAPTCHA yêu cầu thư viện JavaScript của chúng. Hãy chú ý điều đó:
// Wait for reCAPTCHA script to load
await page.waitForFunction(() => {
return typeof window.grecaptcha !== 'undefined'
&& typeof window.grecaptcha.render === 'function';
}, { timeout: 30000 });
// Now extract parameters
const sitekey = await page.evaluate(() => {
const el = document.querySelector('.g-recaptcha');
return el?.getAttribute('data-sitekey');
});
cho cửa quay
await page.waitForFunction(() => {
return typeof window.turnstile !== 'undefined';
}, { timeout: 30000 });
const sitekey = await page.evaluate(() => {
const el = document.querySelector('.cf-turnstile');
return el?.getAttribute('data-sitekey');
});
Phương pháp 3: Chặn lệnh gọi kết xuất
Truy cập thư viện CAPTCHA trước khi nó hiển thị:
// Inject before page scripts run
await page.evaluateOnNewDocument(() => {
window.__captchaDetected = null;
// Hook grecaptcha.render
let _grecaptcha;
Object.defineProperty(window, 'grecaptcha', {
set(val) {
_grecaptcha = val;
const origRender = val.render;
val.render = function(container, params) {
window.__captchaDetected = {
type: 'recaptcha',
sitekey: params.sitekey,
callback: params.callback?.name,
container: typeof container === 'string' ? container : container.id,
};
return origRender.apply(this, arguments);
};
},
get() { return _grecaptcha; },
});
});
await page.goto('https://example.com/signup');
// Trigger the CAPTCHA (click, scroll, etc.)
await page.click('#show-form');
// Wait for detection
await page.waitForFunction(() => window.__captchaDetected !== null, {
timeout: 30000,
});
const detected = await page.evaluate(() => window.__captchaDetected);
console.log('Detected:', detected);
// { type: 'recaptcha', sitekey: '6Le-wvkS...', callback: 'onCaptcha', container: 'recaptcha-box' }
Python (Selenium): Đang chờ CAPTCHA lười biếng
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://staging.example.com/qa-login")
# Trigger the CAPTCHA loading
submit = driver.find_element(By.ID, "submit-btn")
submit.click()
# Wait for CAPTCHA to appear
try:
captcha_el = WebDriverWait(driver, 30).until(
EC.presence_of_element_located((
By.CSS_SELECTOR,
".g-recaptcha, .cf-turnstile, .h-captcha"
))
)
sitekey = captcha_el.get_attribute("data-sitekey")
captcha_class = captcha_el.get_attribute("class")
if "g-recaptcha" in captcha_class:
captcha_type = "recaptcha"
elif "cf-turnstile" in captcha_class:
captcha_type = "turnstile"
else:
captcha_type = "hcaptcha"
print(f"Type: {captcha_type}, Sitekey: {sitekey}")
except Exception:
print("No CAPTCHA appeared within 30 seconds")
Đang chờ iframe (reCAPTCHA)
# reCAPTCHA loads an iframe even when the div exists but the script is still loading
WebDriverWait(driver, 30).until(
EC.presence_of_element_located((
By.CSS_SELECTOR,
"iframe[src*='recaptcha'], iframe[src*='challenges.cloudflare.com']"
))
)
print("CAPTCHA iframe loaded")
Phát hiện hoàn chỉnh + giải quyết luồng
import requests
import time
def detect_and_solve(driver, api_key, trigger_action=None):
"""Detect a lazy-loaded CAPTCHA, solve it, and inject the token."""
# 1. Trigger the CAPTCHA
if trigger_action:
trigger_action(driver)
# 2. Wait for it to appear
captcha_el = WebDriverWait(driver, 30).until(
EC.presence_of_element_located((
By.CSS_SELECTOR,
".g-recaptcha, .cf-turnstile, .h-captcha"
))
)
sitekey = captcha_el.get_attribute("data-sitekey")
page_url = driver.current_url
captcha_class = captcha_el.get_attribute("class")
# 3. Determine type and method
if "g-recaptcha" in captcha_class:
method, key_param, token_field = "userrecaptcha", "googlekey", "g-recaptcha-response"
elif "cf-turnstile" in captcha_class:
method, key_param, token_field = "turnstile", "sitekey", "cf-turnstile-response"
else:
method, key_param, token_field = "hcaptcha", "sitekey", "h-captcha-response"
# 4. Solve with CaptchaAI
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": api_key, "method": method,
key_param: sitekey, "pageurl": page_url, "json": "1",
}).json()
task_id = resp["request"]
for _ in range(24):
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"]
break
# 5. Inject
driver.execute_script(f"""
const el = document.querySelector('textarea[name="{token_field}"], input[name="{token_field}"]');
if (el) el.value = arguments[0];
""", token)
return token
Khắc phục sự cố
| Vấn đề | Nguyên nhân | Cách xử lý |
|---|---|---|
| CAPTCHA không bao giờ xuất hiện | Hành động kích hoạt sai | Kiểm tra trang để tìm yếu tố kích hoạt CAPTCHA |
| Khóa trang web không có giá trị | Phần tử tồn tại nhưng tập lệnh chưa chạy | Đợi iframe CAPTCHA, không chỉ div |
| Người quan sát bỏ lỡ nó | CAPTCHA đã có sẵn ở đó | Kiểm tra các phần tử hiện có trước khi thiết lập trình quan sát |
| Hết giờ | CAPTCHA chỉ tải cho người dùng thực | Sử dụng trình duyệt hoàn chỉnh với dấu vân tay thực tế |
Câu hỏi thường gặp
Làm cách nào để biết CAPTCHA có được tải từng phần hay không?
Xem nguồn trang (Ctrl+U). Nếu div hoặc tập lệnh CAPTCHA không có ở đó nhưng xuất hiện khi bạn tương tác với trang thì trang đó được tải từng phần.
Tính năng này có hoạt động với các trình duyệt không có giao diện người dùng không?
Vâng, hãy cẩn thận. Một số trang web chỉ tải CAPTCHA cho các trình duyệt không có giao diện người dùng. Sử dụng headless: 'new' trong Puppeteer hoặc plugin tàng hình.
Giải bất kỳ CAPTCHA nào bằng CaptchaAI
Nhận khóa API của bạn tạicaptchaai.com.
Hướng dẫn liên quan
- Bảng điều khiển trình duyệt Phát hiện CAPTCHA
- Xử lý nhiều CAPTCHA trên một trang
- Trích xuất thông số reCAPTCHA