Dans beaucoup de workflows Node.js, lancer un navigateur complet est disproportionné. Si votre besoin se limite à soumettre un challenge, récupérer un token puis l'injecter dans une requête HTTP, Axios suffit largement. Vous réduisez la consommation mémoire, vous simplifiez le déploiement et vous gardez une architecture plus facile à exploiter côté serveur.
CaptchaAI prend ici en charge la résolution, pendant qu'Axios gère les appels HTTP de soumission et de reprise du workflow.
Prérequis
| Exigence | Détails |
|---|---|
| Node.js | 16+ |
| axios | 1.x |
| Clé API CaptchaAI | Disponible ici |
npm install axios
Client CaptchaAI minimal
const axios = require("axios");
class CaptchaAI {
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 });
const text = resp.data;
if (!String(text).startsWith("OK|")) {
throw new Error(`Submit failed: ${text}`);
}
return String(text).split("|")[1];
}
async poll(taskId, timeoutMs = 300000) {
const deadline = Date.now() + timeoutMs;
const params = { key: this.apiKey, action: "get", id: taskId };
while (Date.now() < deadline) {
await new Promise((r) => setTimeout(r, 5000));
const resp = await axios.get(`${this.baseUrl}/res.php`, { params });
const text = String(resp.data);
if (text === "CAPCHA_NOT_READY") continue;
if (text.startsWith("OK|")) return text.split("|").slice(1).join("|");
throw new Error(`Solve failed: ${text}`);
}
throw new Error(`Timeout after ${timeoutMs}ms for task ${taskId}`);
}
async solve(params, timeoutMs = 300000) {
const taskId = await this.submit(params);
return this.poll(taskId, timeoutMs);
}
async getBalance() {
const resp = await axios.get(`${this.baseUrl}/res.php`, {
params: { key: this.apiKey, action: "getbalance" },
});
return parseFloat(resp.data);
}
}
module.exports = CaptchaAI;
Résoudre reCAPTCHA v2 sans navigateur
const CaptchaAI = require("./captchaai");
async function main() {
const solver = new CaptchaAI(process.env.CAPTCHAAI_API_KEY);
// Solve the CAPTCHA without opening any browser
const token = await solver.solve({
method: "userrecaptcha",
googlekey: "6Le-wvkS...",
pageurl: "https://example.com/login",
});
// Submit form with the token using Axios
const resp = await axios.post("https://example.com/login", {
username: "user",
password: "pass",
"g-recaptcha-response": token,
});
console.log(`Login response: ${resp.status}`);
}
main().catch(console.error);
Résoudre Turnstile sans navigateur
const token = await solver.solve({
method: "turnstile",
sitekey: "0x4AAAAA...",
pageurl: "https://example.com",
});
// Submit with Turnstile token
const resp = await axios.post("https://example.com/api/verify", {
"cf-turnstile-response": token,
data: "payload",
});
Résoudre un CAPTCHA image
const fs = require("fs");
const imageBuffer = fs.readFileSync("captcha.png");
const imageB64 = imageBuffer.toString("base64");
const text = await solver.solve({
method: "base64",
body: imageB64,
});
console.log(`CAPTCHA text: ${text}`);
// Submit form with solved text
const resp = await axios.post("https://example.com/verify", {
captcha: text,
other_data: "value",
});
Workflow complet de scraping HTTP
Voici un exemple de pipeline complet sans navigateur pour récupérer une page protégée, extraire la clé du challenge et soumettre le formulaire.
const CaptchaAI = require("./captchaai");
const axios = require("axios");
const cheerio = require("cheerio");
async function scrapeProtectedPage(url) {
const solver = new CaptchaAI(process.env.CAPTCHAAI_API_KEY);
// Step 1: Fetch the page
const page = await axios.get(url);
const $ = cheerio.load(page.data);
// Step 2: Extract the reCAPTCHA site key
const siteKey = $(".g-recaptcha").attr("data-sitekey");
if (!siteKey) {
console.log("No CAPTCHA found, returning page content");
return page.data;
}
// Step 3: Solve the CAPTCHA
console.log(`Solving CAPTCHA for ${url}...`);
const token = await solver.solve({
method: "userrecaptcha",
googlekey: siteKey,
pageurl: url,
});
// Step 4: Submit form with token
const formAction = $("form").attr("action") || url;
const formData = {};
$("form input").each((_, el) => {
const name = $(el).attr("name");
const value = $(el).attr("value") || "";
if (name) formData[name] = value;
});
formData["g-recaptcha-response"] = token;
const result = await axios.post(formAction, new URLSearchParams(formData), {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
});
return result.data;
}
scrapeProtectedPage("https://example.com/data")
.then((data) => console.log("Success:", typeof data))
.catch(console.error);
Résolution en parallèle
async function solveBatch(urls, siteKey) {
const solver = new CaptchaAI(process.env.CAPTCHAAI_API_KEY);
const promises = urls.map(async (url) => {
try {
const token = await solver.solve({
method: "userrecaptcha",
googlekey: siteKey,
pageurl: url,
});
return { url, token, error: null };
} catch (error) {
return { url, token: null, error: error.message };
}
});
const results = await Promise.all(promises);
const solved = results.filter((r) => r.token);
console.log(`Solved ${solved.length}/${urls.length}`);
return results;
}
Depannage
| Erreur | Cause probable | Correctif |
|---|---|---|
AxiosError: getaddrinfo ENOTFOUND |
Problème DNS | Vérifiez le réseau et la résolution de nom |
Submit failed: ERROR_WRONG_USER_KEY |
Mauvaise clé API | Contrôlez la clé depuis le dashboard |
Submit failed: ERROR_ZERO_BALANCE |
Solde insuffisant | Rechargez le compte |
| Token refusé par le site | Token expiré ou mauvais contexte | Soumettez-le rapidement après résolution |
FAQ
Pourquoi éviter un navigateur ?
Parce qu'un navigateur coûte cher en RAM, en temps de démarrage et en maintenance. Quand une requête HTTP suffit, Axios plus CaptchaAI donnent un pipeline beaucoup plus léger.
Quand faut-il tout de même un navigateur ?
Lorsque le site dépend fortement de JavaScript pour construire la page, calculer les champs ou déclencher la soumission. Dans ce cas, le CAPTCHA n'est pas le seul problème.
Peut-on remplacer Axios par fetch ?
Oui. Si vous êtes déjà sur Node.js récent, fetch natif fonctionne aussi. L'intérêt de cet article est surtout de montrer le pattern HTTP sans navigateur.
Guides connexes
- Tutoriel Captcha Scraping Node.js
- Intégration HTTPX + CaptchaAI
- cURL + CaptchaAI CLI