Trường Hợp Sử Dụng

Puppeteer giải CAPTCHA bằng Node.js và CaptchaAI

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

  1. Puppeteer điều hướng đến trang có CAPTCHA
  2. Tập lệnh của bạn trích xuất khóa trang CAPTCHA từ DOM
  3. CaptchaAI giải quyết thách thức phía máy chủ
  4. 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

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