Node.js zeichnet sich durch I/O-heavy-Scraping-Workloads aus. Wenn Zielseiten CAPTCHAs bereitstellen, löst die API von CaptchaAI diese, während Ihr Skript die HTTP-Anfragen verarbeitet. Dieses Tutorial behandelt den gesamten Workflow mit Axios und Cheerio.
Anforderungen
| Anforderung | Einzelheiten |
|---|---|
| Node.js 16+ | Mit npm |
| Axios | npm install axios |
| Cheerio | npm install cheerio |
| CaptchaAI API-Schlüssel | Aus captchaai.com |
Das CaptchaAI Solver-Modul
// captcha-solver.js
const axios = require("axios");
class CaptchaSolver {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = "https://ocr.captchaai.com";
}
async _submit(params) {
params.key = this.apiKey;
const resp = await axios.get(`${this.baseUrl}/in.php`, { params });
if (!resp.data.startsWith("OK|")) {
throw new Error(`Submit error: ${resp.data}`);
}
return resp.data.split("|")[1];
}
async _poll(taskId, timeout = 300000) {
const deadline = Date.now() + timeout;
while (Date.now() < deadline) {
await new Promise((r) => setTimeout(r, 5000));
const resp = await axios.get(`${this.baseUrl}/res.php`, {
params: { key: this.apiKey, action: "get", id: taskId },
});
if (resp.data === "CAPCHA_NOT_READY") continue;
if (resp.data.startsWith("OK|")) return resp.data.split("|")[1];
throw new Error(`Solve error: ${resp.data}`);
}
throw new Error("Solve timed out");
}
async solveRecaptchaV2(siteKey, pageUrl) {
const taskId = await this._submit({
method: "userrecaptcha",
googlekey: siteKey,
pageurl: pageUrl,
});
return this._poll(taskId);
}
async solveRecaptchaV3(siteKey, pageUrl, action = "verify") {
const taskId = await this._submit({
method: "userrecaptcha",
googlekey: siteKey,
pageurl: pageUrl,
version: "v3",
action,
});
return this._poll(taskId);
}
async solveTurnstile(siteKey, pageUrl) {
const taskId = await this._submit({
method: "turnstile",
sitekey: siteKey,
pageurl: pageUrl,
});
return this._poll(taskId);
}
}
module.exports = CaptchaSolver;
Scraping einer reCAPTCHA-geschützten Seite
const axios = require("axios");
const cheerio = require("cheerio");
const CaptchaSolver = require("./captcha-solver");
const solver = new CaptchaSolver("YOUR_API_KEY");
async function scrapeProtectedPage(url) {
// Step 1: Load the page
const { data: html } = await axios.get(url, {
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
},
});
const $ = cheerio.load(html);
// Step 2: Extract site key
const siteKey = $(".g-recaptcha").attr("data-sitekey");
if (!siteKey) {
console.log("No CAPTCHA found, page loaded directly");
return html;
}
console.log("Site key found:", siteKey);
// Step 3: Solve the CAPTCHA
const token = await solver.solveRecaptchaV2(siteKey, url);
console.log("Token received:", token.substring(0, 50));
// Step 4: Submit with the token
const result = await axios.post(
url,
new URLSearchParams({
"g-recaptcha-response": token,
q: "search query",
}),
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
},
}
);
return result.data;
}
Mehrere Seiten gleichzeitig durchsuchen
async function scrapePages(urls, siteKey, concurrency = 3) {
const results = [];
const queue = [...urls];
const worker = async () => {
while (queue.length > 0) {
const url = queue.shift();
try {
const token = await solver.solveRecaptchaV2(siteKey, url);
const { data } = await axios.post(
url,
new URLSearchParams({ "g-recaptcha-response": token }),
{
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
},
}
);
results.push({ url, data, success: true });
console.log(`Scraped: ${url}`);
} catch (err) {
results.push({ url, error: err.message, success: false });
console.error(`Failed: ${url} - ${err.message}`);
}
}
};
// Run workers concurrently
const workers = Array(concurrency)
.fill(null)
.map(() => worker());
await Promise.all(workers);
return results;
}
// Usage
const urls = [
"https://example.com/page/1",
"https://example.com/page/2",
"https://example.com/page/3",
];
const results = await scrapePages(urls, "6Le-wvkS...", 3);
Umgang mit Cookies und Sitzungen
Verwenden Sie Axios mit Cookie-Persistenz für Websites, die Sitzungscookies erfordern:
const { wrapper } = require("axios-cookiejar-support");
const { CookieJar } = require("tough-cookie");
const jar = new CookieJar();
const client = wrapper(
axios.create({
jar,
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
},
})
);
async function scrapeWithSession(url, siteKey) {
// Initial page load sets cookies
await client.get(url);
// Solve CAPTCHA
const token = await solver.solveRecaptchaV2(siteKey, url);
// Submit with maintained cookies
const result = await client.post(
url,
new URLSearchParams({ "g-recaptcha-response": token })
);
return result.data;
}
Ergebnisse mit Cheerio analysieren
function parseResults(html) {
const $ = cheerio.load(html);
const items = [];
$(".result-item").each((_, el) => {
items.push({
title: $(el).find(".title").text().trim(),
url: $(el).find("a").attr("href"),
description: $(el).find(".description").text().trim(),
});
});
return items;
}
Fehlerbehebung
| Problem | Ursache | Lösung |
|---|---|---|
CAPTCHA_NOT_READY führt eine Endlosschleife durch |
Falscher Site-Schlüssel oder langsame Lösung | Site-Schlüssel überprüfen; Timeout erhöhen |
403 Forbidden auf POST |
Fehlende Cookies oder Header | Sitzungscookies verwenden; Referer-Header hinzufügen |
| Cheerio kann keine Elemente finden | Dynamischer Inhalt | Verwenden Sie Puppeteer für JS-gerenderte Websites |
ECONNREFUSED |
Rate durch Zielsite begrenzt | Verzögerungen hinzufügen; Proxys drehen |
FAQ
Wann sollte ich Puppeteer anstelle von Axios verwenden?
Verwenden Sie axios + cheerio, wenn die Zielseite HTML mit Standardformularübermittlungen zurückgibt. Verwenden Sie Puppeteer, wenn die Site die Ausführung von JavaScript, dynamisches Rendering oder komplexe Benutzerinteraktionen erfordert.
Kann ich mehrere CAPTCHAs gleichzeitig lösen?
Ja. Senden Sie mehrere CAPTCHA-Aufgaben gleichzeitig an CaptchaAI und fragen Sie jedes Ergebnis ab. Das obige Beispiel für gleichzeitiges Scraping veranschaulicht dieses Muster.
Wie gehe ich mit Cloudflare-geschützten Websites um?
Wenn die Site Turnstile verwendet, verwenden Sie solver.solveTurnstile(). Für vollständige Cloudflare-Challenge-Seiten verwenden Sie Cloudflare Challenge lösen, was cf_clearance-Cookies zurückgibt.
Verwandte Leitfäden
- Puppeteer CAPTCHA-Lösung mit Node.js
- CAPTCHA-Scraping mit Python
- Proxy-Rotation für CAPTCHA-Scraping