Integrations

Axios + CaptchaAI: CAPTCHA'ları Tarayıcı Olmadan Çözün

Sunucu tarafında CAPTCHA çözmek için tam bir tarayıcı ayağa kaldırmak çoğu zaman iş yükünüzün en pahalı ve en kırılgan parçasıdır. İyi haber şu: reCAPTCHA, Turnstile ve resim CAPTCHA'larını yalnızca Axios ve birkaç saf HTTP isteğiyle çözebilirsiniz — ne Puppeteer, ne Playwright, ne de headless tarayıcı yükü. CaptchaAI çözümü uzaktan üretir; siz yalnızca dönen token'ı alıp formunuza yerleştirirsiniz.

Bu rehber, Node.js için yeniden kullanılabilir bir CaptchaAI istemcisi kurar, ardından reCAPTCHA v2'den Turnstile'a ve resim CAPTCHA'larına kadar her türü aynı istemciyle çözer. Tüm örnekler çalışan koddur ve doğrudan iş akışınıza kopyalanabilir.

Tarayıcısız çözüm neden daha hafif?

Bir headless tarayıcı örneği tipik olarak 200-500 MB RAM tüketir; aynı işi saf HTTP ile yapan CaptchaAI istemcisi ise yaklaşık 5 MB ile yetinir. Sunucu tarafı otomasyonda bu, örnek başına 40-100 kat daha az bellek demektir — ve konteyner başına çok daha fazla eşzamanlı iş demektir.

Fiyatlandırma modeli de bu yaklaşımı ödüllendirir. CaptchaAI çözüm başına değil, eşzamanlı thread başına ücretlendirir ve her planda thread başına sınırsız çözüm vardır. En düşük plan olan BASIC ($15/ay, 5 thread) aynı anda beş CAPTCHA'yı işleme kapasitesi verir; hacim büyüdükçe STANDARD ($30/ay, 15 thread) veya ADVANCE ($90/ay, 50 thread) planlarına geçebilirsiniz. Ücretlendirme USD üzerinden ve aylık sabittir — TL kur oynaklığından etkilenmeyen öngörülebilir bir gider kalemi, freelance otomasyon işi yapan geliştiriciler için pratik bir avantajdır.

Başlamadan önce gerekenler

Gereksinim Ayrıntılar
Node.js 16+
axios 1.x
CaptchaAI API anahtarı Ücretsiz API anahtarı alın

Tek harici bağımlılık Axios'tur. Kazıma örneği için ayrıca cheerio kullanacağız, ama çekirdek çözüm akışı yalnızca Axios ile çalışır.

npm install axios

Yeniden kullanılabilir CaptchaAI istemcisi

Aşağıdaki sınıf tüm mantığı tek yerde toplar. submit metodu görevi in.php uç noktasına gönderir ve bir görev kimliği döndürür; poll metodu res.php uç noktasını beş saniyede bir sorgulayarak sonucu bekler; solve ise ikisini tek çağrıda birleştirir. Varsayılan zaman aşımı 300.000 ms'dir (5 dakika) ve getBalance ile hesap bakiyenizi kontrol edebilirsiniz.

Bu istemciyi captchaai.js olarak kaydedin ve tüm örneklerde yeniden kullanın:

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;

reCAPTCHA v2'yi tarayıcı olmadan çözün

En yaygın senaryo reCAPTCHA v2'dir. googlekey alanına sayfanın sitekey değerini, pageurl alanına da CAPTCHA'nın göründüğü URL'yi verirsiniz. Dönen token'ı formun g-recaptcha-response alanına yerleştirip yine Axios ile gönderirsiniz — hiçbir noktada tarayıcı açılmaz.

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://staging.example.com/qa-login",
  });

  // Submit form with the token using Axios
  const resp = await axios.post("https://staging.example.com/qa-login", {
    username: "user",
    password: "pass",
    "g-recaptcha-response": token,
  });

  console.log(`Login response: ${resp.status}`);
}

main().catch(console.error);

Cloudflare Turnstile'ı çözün

Turnstile için yalnızca method değerini turnstile yapıp sitekey ve pageurl vermeniz yeterlidir. Bu kez dönen token, formun cf-turnstile-response alanına gider. Token alanının adı türden türe değişir; reCAPTCHA'nın g-recaptcha-response alanıyla karıştırmayın.

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",
});

Resim (image) CAPTCHA'larını çözün

Klasik metin tabanlı resim CAPTCHA'ları için görüntüyü base64'e çevirip method: "base64" ile gönderirsiniz. Bu sefer yanıt bir token değil, doğrudan çözülmüş metindir ve onu formun ilgili alanına koyarsınız.

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",
});

Uçtan uca kazıma akışı

Gerçek dünyada sitekey'i çoğu zaman elle bilmezsiniz; sayfanın HTML'inden okumanız gerekir. Aşağıdaki akış sayfayı çeker, cheerio ile sitekey'i çıkarır, CAPTCHA'yı çözer ve formu tüm gizli alanlarıyla birlikte gönderir. Bir e-ticaret ekibinin staging ortamında ödeme (checkout) akışını otomatik test etmesi tam da bu desenle çalışır.

Not: kazıdığınız veri kişisel veri içeriyorsa Türkiye'de KVKK kapsamına girer. Bu tür akışları yalnızca yetkili olduğunuz QA ve veri toplama senaryolarında, kendi staging ortamınızda çalıştırın.

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);

Toplu ve eşzamanlı çözüm

Tarayıcısız yaklaşımın en büyük kazancı burada görünür: yaklaşım hafif olduğu için yüzlerce isteği tek makinede paralel çalıştırabilirsiniz. Eşzamanlılığın üst sınırını planınızın thread sayısı belirler — BASIC ile 5, ADVANCE ile 50 CAPTCHA aynı anda işlenir. Promise.all ile toplu gönderim yaparken hata yönetimini her görev için ayrı tutun ki tek bir başarısızlık toptan çökmesin.

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;
}

Sık karşılaşılan hatalar ve çözümleri

Üretimde en çok görülen dört durum ve pratik çözümleri aşağıda. Token satırındaki en kritik nokta: token'ın kısa bir ömrü vardır, bu yüzden çözümden hemen sonra göndermelisiniz.

Hata Sebep Düzeltme
AxiosError: getaddrinfo ENOTFOUND DNS sorunu Ağ bağlantısını kontrol edin
Submit failed: ERROR_WRONG_USER_KEY Geçersiz API anahtarı Anahtarı kontrol panelinden doğrulayın
Submit failed: ERROR_ZERO_BALANCE Bakiye yok Hesaba bakiye ekleyin
Token hedef site tarafından reddedildi Token'ın süresi doldu Token'ı 60 saniye içinde gönderin

Sık sorulan sorular

Axios ile hangi CAPTCHA türlerini çözebilirim?

reCAPTCHA v2 ve v3, Cloudflare Turnstile ve metin tabanlı resim CAPTCHA'larını bu istemciyle çözebilirsiniz. hCaptcha ve FunCaptcha ise CaptchaAI tarafından desteklenmiyor; bu türleri çözdüğünü iddia eden hiçbir örneğe güvenmeyin.

CaptchaAI hCaptcha veya FunCaptcha'yı destekliyor mu?

Hayır. Her ikisi de şu an desteklenmiyor. GeeTest v4 için ise yalnızca "çok yakında" durumu geçerlidir; mevcut değildir.

Eşzamanlı olarak kaç CAPTCHA çözebilirim?

Aynı anda işlenen CAPTCHA sayısı planınızın thread sayısına bağlıdır: BASIC ($15/ay, 5 thread) beş, ADVANCE ($90/ay, 50 thread) elli eşzamanlı çözüm sağlar. Thread başına çözüm sınırı yoktur.

Axios yerine fetch kullanabilir miyim?

Evet. Node.js 18+ yerleşik fetch'i içerir ve CaptchaAI API parametreleri birebir aynıdır. Tek fark isteklerin nasıl yazıldığıdır; çözüm akışı değişmez.

Token neden hedef site tarafından reddedildi?

En yaygın neden token'ın süresinin dolmasıdır. Çözümden sonra token'ı genellikle 60 saniye içinde göndermelisiniz ve pageurl çözüm anında verdiğiniz URL ile aynı olmalıdır.

İlgili Kılavuzlar

Bu makale için yorumlar devre dışı bırakılmıştır.