Node.js превосходно справляется с рабочими нагрузками I/O-heavy. Когда целевые сайты обрабатывают CAPTCHA, API CaptchaAI решает их, пока ваш скрипт обрабатывает HTTP-запросы. В этом руководстве рассматривается весь рабочий процесс с использованием axios и Cheerio.
Требования
| Требование | Подробности |
|---|---|
| Node.js 16+ | С НПМ |
| аксиомы | npm install axios |
| приветствие | npm install cheerio |
| CaptchaAI API-ключ | Отcaptchaai.com |
Решающий модуль CaptchaAI
// 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;
Очистка страницы, защищенной reCAPTCHA
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;
}
Парсинг нескольких страниц одновременно
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);
Обработка файлов cookie и сеансов
Используйте axios с сохранением файлов cookie для сайтов, которым требуются сеансовые файлы cookie:
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;
}
Анализ результатов с помощью Cheerio
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;
}
Поиск неисправностей
| Проблема | Причина | Исправить |
|---|---|---|
CAPTCHA_NOT_READY зацикливается на неопределенный срок. |
Неправильный ключ сайта или медленное решение | Проверьте ключ сайта; увеличить таймаут |
403 Forbidden в POST |
Отсутствуют файлы cookie или заголовки. | Использовать сеансовые файлы cookie; добавить заголовок Referer |
| Cheerio не может найти элементы | Динамический контент | Используйте Puppeteer для сайтов, отображаемых на JS. |
ECONNREFUSED |
Ставка ограничена целевым сайтом | Добавьте задержки; ротация прокси |
Часто задаваемые вопросы
Когда мне следует использовать Puppeteer вместо axios?
Используйте axios + Cheerio, когда целевой сайт возвращает HTML со стандартной отправкой формы. Используйте Puppeteer, когда сайт требует выполнения JavaScript, динамического рендеринга или сложного взаимодействия с пользователем.
Могу ли я решать несколько CAPTCHA одновременно?
Да. Отправьте несколько задач CAPTCHA в CaptchaAI одновременно и опросите каждый результат. Приведенный выше пример параллельного парсинга демонстрирует эту закономерность.
Как обращаться с сайтами, защищенными Cloudflare?
Если на сайте используется Cloudflare Turnstile, используйте solver.solveTurnstile(). Для полных страниц задач Cloudflare используйтестраница Cloudflare-защиты в staging решениекоторый возвращает файлы cookie qa_validation_cookie.
Связанные руководства
- Решение CAPTCHA Puppeteer с помощью Node.js
- Парсинг CAPTCHA с помощью Python
- Ротация прокси для парсинга CAPTCHA