Intégrations

Utiliser Axios et CaptchaAI pour résoudre des CAPTCHA sans navigateur

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
Les commentaires sont désactivés pour cet article.