Puppeteer, Node.js otomasyonu için başvurulacak headless tarayıcıdır. Hedef siteler CAPTCHA'lar sunduğunda, CaptchaAI'nin API'si bunları harici olarak çözer; Puppeteer parametreleri çıkarır, CaptchaAI jetonu döndürür ve Puppeteer onu geri enjekte eder.
Gereksinimler
| Gereksinim | Ayrıntılar |
|---|---|
| Node.js 16+ | npm ile |
| Puppeteer | npm install puppeteer |
| eksenler | npm install axios |
| CaptchaAI API anahtarı | İtibarencaptchaai.com |
Nasıl Çalışır?
- Puppeteer CAPTCHA ile sayfaya gider
- Komut dosyanız CAPTCHA site anahtarını DOM'dan çıkarıyor
- CaptchaAI sunucu tarafındaki zorluğu çözüyor
- Komut dosyanız belirteci enjekte eder ve formu gönderir
Adım 1: Çözücü Modülünü Oluşturun
// 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 };
Adım 2: Puppeteer'ı Gizli Olarak Kurun
const puppeteer = require("puppeteer");
async function createBrowser() {
const browser = await puppeteer.launch({
headless: "new",
args: [
"--no-sandbox",
"--disable-setuid-sandbox",
"--no-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 };
}
3. Adım: Bir Sayfada reCAPTCHA'yı çözün
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();
}
}
4. Adım: Geri Aramaları İşleme
Bazı siteler form gönderimi yerine JavaScript geri aramalarını kullanır:
// 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);
Tam Çalışma Örneği
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: ["--no-sandbox"],
});
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();
}
})();
Sorun giderme
| Sorun | Sebep | Düzeltme |
|---|---|---|
page.$eval başarısız oluyor |
CAPTCHA ilk oluşturma işleminden sonra yüklenir | page.waitForSelector('.g-recaptcha')'yi kullanın |
| Jeton çalışmıyor | Gönderilmeden önce süresi dolmuş | Aldıktan hemen sonra enjekte edin |
| Site Puppeteeryı tespit ediyor | Standart yapılandırma eksik | puppeteer (varsayılan yapılandırma)'yi kullanın |
Navigation timeout |
Sayfa gönderildikten sonra gezinmedi | Sitenin form gönderimi yerine AJAX kullanıp kullanmadığını kontrol edin |
SSS
Headless modunu mu yoksa başlı modunu mu kullanmalıyım?
CAPTCHA sunucu tarafında çözüldüğünden, headless mod CaptchaAI ile sorunsuz çalışıyor. Başlık modunu yalnızca hata ayıklama için kullanın.
Puppeteer'ı Cloudflare Turnstile ile kullanabilir miyim?
Evet. data-sitekey'yi .cf-turnstile div'den çıkarın ve method=turnstile'yi CaptchaAI ile kullanın. Yukarıdaki solveTurnstile işlevine bakın.
Bir sayfada birden fazla CAPTCHA'yı nasıl yönetirim?
Her site anahtarını ayrı ayrı çıkarın ve bunları Promise.all() kullanarak paralel olarak çözün.