Puppeteer là trình duyệt headless dành cho tự động hóa Node.js. Khi các trang đích phân phát CAPTCHA, API của CaptchaAI sẽ giải quyết chúng từ bên ngoài — Puppeteer trích xuất các tham số, CaptchaAI trả về mã thông báo và Puppeteer sẽ tiêm lại mã đó.
Yêu cầu
| Yêu cầu | Chi tiết |
|---|---|
| Node.js 16+ | Với npm |
| Puppeteer | npm install puppeteer |
| trục | npm install axios |
| Khóa API CaptchaAI | Từcaptchaai.com |
Nó hoạt động như thế nào
- Puppeteer điều hướng đến trang có CAPTCHA
- Tập lệnh của bạn trích xuất khóa trang CAPTCHA từ DOM
- CaptchaAI giải quyết thách thức phía máy chủ
- Tập lệnh của bạn chèn mã thông báo và gửi biểu mẫu
Bước 1: Tạo mô-đun bộ giải
// solver.js
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
const POLL_INTERVAL = 5000;
const MAX_ATTEMPTS = 60;
async function solveRecaptchaV2(siteKey, pageUrl) {
// Submit task
const submitResp = await axios.get("https://ocr.captchaai.com/in.php", {
params: {
key: API_KEY,
method: "userrecaptcha",
googlekey: siteKey,
pageurl: pageUrl,
},
});
if (!submitResp.data.startsWith("OK|")) {
throw new Error(`Submit failed: ${submitResp.data}`);
}
const taskId = submitResp.data.split("|")[1];
console.log(`Task submitted: ${taskId}`);
// Poll for result
for (let i = 0; i < MAX_ATTEMPTS; i++) {
await new Promise((r) => setTimeout(r, POLL_INTERVAL));
const result = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: taskId },
});
if (result.data === "CAPCHA_NOT_READY") continue;
if (result.data.startsWith("OK|")) {
return result.data.split("|")[1];
}
throw new Error(`Solve failed: ${result.data}`);
}
throw new Error("Solve timed out");
}
async function solveTurnstile(siteKey, pageUrl) {
const submitResp = await axios.get("https://ocr.captchaai.com/in.php", {
params: {
key: API_KEY,
method: "turnstile",
sitekey: siteKey,
pageurl: pageUrl,
},
});
if (!submitResp.data.startsWith("OK|")) {
throw new Error(`Submit failed: ${submitResp.data}`);
}
const taskId = submitResp.data.split("|")[1];
for (let i = 0; i < MAX_ATTEMPTS; i++) {
await new Promise((r) => setTimeout(r, POLL_INTERVAL));
const result = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: taskId },
});
if (result.data === "CAPCHA_NOT_READY") continue;
if (result.data.startsWith("OK|")) return result.data.split("|")[1];
throw new Error(`Solve failed: ${result.data}`);
}
throw new Error("Solve timed out");
}
module.exports = { solveRecaptchaV2, solveTurnstile };
Bước 2: Thiết lập người múa rối với khả năng tàng hình
const puppeteer = require("puppeteer");
async function createBrowser() {
const browser = await puppeteer.launch({
headless: "new",
args: [
"--no-sandbox",
"--disable-setuid-sandbox",
"",
],
});
const page = await browser.newPage();
await page.setUserAgent(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
);
// Hide automation indicators
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, "webdriver", { get: () => false });
});
return { browser, page };
}
Bước 3: Giải reCAPTCHA trên một trang
const { solveRecaptchaV2 } = require("./solver");
async function scrapeWithCaptcha(url) {
const { browser, page } = await createBrowser();
try {
await page.goto(url, { waitUntil: "networkidle2" });
// Extract site key
const siteKey = await page.$eval(
".g-recaptcha",
(el) => el.getAttribute("data-sitekey")
);
console.log("Site key:", siteKey);
// Solve with CaptchaAI
const token = await solveRecaptchaV2(siteKey, url);
console.log("Token received:", token.substring(0, 50));
// Inject token
await page.evaluate((token) => {
document.getElementById("g-recaptcha-response").innerHTML = token;
document.getElementById("g-recaptcha-response").style.display = "";
}, token);
// Submit the form
await page.click('button[type="submit"]');
await page.waitForNavigation({ waitUntil: "networkidle2" });
// Scrape the content
const content = await page.content();
console.log("Page loaded successfully");
return content;
} finally {
await browser.close();
}
}
Bước 4: Xử lý cuộc gọi lại
Một số trang web sử dụng lệnh gọi lại JavaScript thay vì gửi biểu mẫu:
// Trigger the reCAPTCHA callback
await page.evaluate((token) => {
// Method 1: Direct callback
if (typeof ___grecaptcha_cfg !== "undefined") {
const clients = ___grecaptcha_cfg.clients;
Object.keys(clients).forEach((key) => {
const client = clients[key];
// Find the callback function
const findCallback = (obj) => {
for (const prop in obj) {
if (typeof obj[prop] === "function") {
obj[prop](token);
return true;
}
if (typeof obj[prop] === "object" && obj[prop] !== null) {
if (findCallback(obj[prop])) return true;
}
}
return false;
};
findCallback(client);
});
}
}, token);
Ví dụ làm việc đầy đủ
const puppeteer = require("puppeteer");
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
async function solveCaptcha(siteKey, pageUrl) {
const submit = await axios.get("https://ocr.captchaai.com/in.php", {
params: {
key: API_KEY,
method: "userrecaptcha",
googlekey: siteKey,
pageurl: pageUrl,
},
});
const taskId = submit.data.split("|")[1];
while (true) {
await new Promise((r) => setTimeout(r, 5000));
const result = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: taskId },
});
if (result.data === "CAPCHA_NOT_READY") continue;
if (result.data.startsWith("OK|")) return result.data.split("|")[1];
throw new Error(result.data);
}
}
(async () => {
const browser = await puppeteer.launch({
headless: "new",
args: [""],
});
const page = await browser.newPage();
try {
await page.goto("https://staging.example.com/qa-login", {
waitUntil: "networkidle2",
});
// Get the site key
const siteKey = await page.$eval(".g-recaptcha", (el) =>
el.getAttribute("data-sitekey")
);
// Solve
const token = await solveCaptcha(siteKey, page.url());
// Inject and submit
await page.evaluate((t) => {
document.getElementById("g-recaptcha-response").innerHTML = t;
}, token);
await page.click("#submit-btn");
await page.waitForNavigation();
console.log("Done:", page.url());
} finally {
await browser.close();
}
})();
Khắc phục sự cố
| Vấn đề | Nguyên nhân | Cách xử lý |
|---|---|---|
page.$eval không thành công |
Tải CAPTCHA sau lần hiển thị đầu tiên | Sử dụng page.waitForSelector('.g-recaptcha') |
| Mã thông báo không hoạt động | Hết hạn trước khi gửi | Tiêm ngay sau khi nhận |
| Trang web phát hiện Puppeteer | Thiếu cấu hình QA chuẩn | Sử dụng puppeteer (cấu hình QA) |
Navigation timeout |
Trang không điều hướng sau khi gửi | Kiểm tra xem trang web có sử dụng AJAX thay vì đăng bài không |
Câu hỏi thường gặp
Tôi nên sử dụng chế độ headless hay có đầu?
Chế độ headless hoạt động tốt với CaptchaAI vì CAPTCHA được giải quyết phía máy chủ. Chỉ sử dụng chế độ có giao diện để gỡ lỗi.
Tôi có thể sử dụng Puppeteer với Cloudflare Turnstile không?
Vâng. Trích xuất data-sitekey từ div .cf-turnstile và sử dụng method=turnstile với CaptchaAI. Xem chức năng solveTurnstile ở trên.
Làm cách nào để xử lý nhiều CAPTCHA trên một trang?
Trích xuất từng khóa trang web riêng biệt và giải quyết chúng song song bằng Promise.all().
Hướng dẫn liên quan
- Xử lý CAPTCHA Selenium bằng Python
- Nhà soạn kịch Xử lý CAPTCHA
- Quét CAPTCHA bằng Node.js