Node.js’te Doğru User Agent ile CaptchaFox Nasıl Çözülür

solve captchafox in node.js - How to Solve CaptchaFox in Node.js With the Right User Agent

Node.js ile CaptchaFox çözmek için capskip paketinin captchafox metodunu sitekey ve sayfa URL’siyle çağırın, ardından dönen token’ı cf-captcha-response alanında gönderin. Bu gönderimi, fetch’in sizin yerinize eklemeyeceği üç şeyle birlikte yapın: sayfanın ayarladığı çerezler, bir Referer ve CapSkip’in token’ın yanında döndürdüğü user agent. Node kodlarının çoğunun düştüğü tuzak user agent’tır. Node’un yerleşik fetch’i her sunucuya user agent’ının node olduğunu söyler; token’ın onu üreten tarayıcıdan gelmesini bekleyen bir site de, çözüm ne kadar iyi olursa olsun bu gönderimi reddeder. CapSkip, CaptchaFox desteğini 1.4.0 sürümünde ekledi. Bu rehber anahtarı okumayı, çağrıyı, gönderimi, yeniden denemeleri ve aynı anda birçok kayıt işlemini çalıştırmayı ele alıyor.

Neye ihtiyacınız var

  • Bir Windows makinesinde çalışan CapSkip 1.4.0 veya üzeri. CaptchaFox desteği, Friendly Captcha ve Capy Puzzle ile birlikte bu sürümle geldi.
  • Node.js 20.18.1 veya üzeri; cheerio’nun desteklediği en eski sürüm budur. Yeni bir projede 22 ya da 24 kullanın, çünkü Node 20 Nisan 2026’da destek ömrünün sonuna ulaştı.
  • capskip paketinin 1.3.0 veya üzeri bir sürümü; captchafox metodunu içeren ilk sürüm budur. Ayrıca HTML’yi okumak için de cheerio.
  • Widget’ı gösteren sayfanın URL’si. Sitekey, form alanları ve widget derlemesi hep bu sayfadan elde edilir.
  • Çözücü için bir adres. Local modunda CapSkip 127.0.0.1 üzerinden yalnızca o cihaza yanıt verir; Server modunda ise ağ adresinizi veya genel IP’nizi dinler, böylece başka bir makinedeki bir betik onu API üzerinden çağırabilir. İkisi de şurada ayarlanır: bağlantı ayarları.
# capskip 1.3.0 added captchafox(); cheerio reads the HTML
npm install capskip cheerio

Örnekler, üst düzey await kullanan ES modülleridir. Onları .mjs uzantısıyla kaydedin ya da package.json dosyanızdaki type alanını module olarak ayarlayın, çünkü npm init artık oraya commonjs yazıyor. Projeniz CommonJS ise capskip paketi require ile de yüklenir.

1. Adım: sayfayı çekin, çerezlerini saklayın ve sitekey’i okuyun

Node’un fetch’i çağrılar arasında hiçbir çerezi saklamaz, dolayısıyla sayfanın ayarladığı oturum çerezi, siz formu gönderene kadar çoktan kaybolmuştur. CSRF token’ını bu oturuma bağlayan bir site de gönderimi reddeder. Çerezleri, her Set-Cookie satırını ayrı bir öğe olarak döndüren Headers.getSetCookie() ile kendiniz taşıyın. Node.js ile Friendly Captcha çözme rehberi bu küçük cookie jar’ı daha ayrıntılı açıklıyor.

// npm install capskip cheerio
import * as cheerio from "cheerio";

const PAGE_URL = "https://example.com/signup";

// fetch() keeps no cookies between calls, so carry the page's own.
const jar = new Map();
const page = await fetch(PAGE_URL);
for (const line of page.headers.getSetCookie()) {
  const pair = line.split(";")[0];
  const eq = pair.indexOf("=");
  jar.set(pair.slice(0, eq).trim(), pair.slice(eq + 1).trim());
}
const html = await page.text();
const $ = cheerio.load(html);

Sitekey herkese açıktır, her ziyaretçi için aynıdır ve geleneksel olarak sk_ ile başlar. Çoğu sayfa onu widget’ın kapsayıcısına koyar: captchafox sınıfına ve bir data-sitekey özniteliğine sahip bir div. Widget’ı kendi script’inden oluşturan bir sayfa ise anahtarı bunun yerine bir captchafox.render çağrısına verir. Çektiğiniz HTML’de bunların hiçbiri yoksa DevTools’u açın: anahtar, api.captchafox.com adresine (MAM sayfalarında mam-api.captchafox.com adresine) giden bir istekte /captcha/ sonrasındaki yol parçasıdır.

Oradayken widget’ı hangi derlemenin yüklediğini de kontrol edin. Çoğu site onu cdn.captchafox.com adresinden yükler ve düz bir token bekler. Bazı platformlar ise bunun yerine s.uicdn.com/mampkg/ altından bir paket gömer ve bu siteler MAM_ ile başlayan bir token bekler. Bir MAM sayfası anahtarı o script’in kendi adresinde, ?key= sonrasında taşıyabilir. Aynı CDN ilgisiz paketler de sunduğu için host’a göre değil, captchafox paket yoluna göre eşleştirin.

// The container, matched on the whole class name.
const widget = $(".captchafox").first();
// MAM pages may carry the key in the package's script src instead.
const mamSrc = $('script[src*="mampkg/@mamdev/core.frontend.libs.captchafox"]').attr("src");
const sitekey = widget.attr("data-sitekey")
  ?? (mamSrc && new URL(mamSrc, PAGE_URL).searchParams.get("key"))
  ?? html.match(/captchafox\.render\([\s\S]{0,300}?sitekey\s*:\s*["']([^"']+)/)?.[1];
const form = widget.length ? widget.closest("form") : $("form").first();

console.log(sitekey, Boolean(mamSrc));   // a MAM page needs a MAM_ token

cheerio’nun sınıf seçicisi sınıf adlarını bütün olarak eşleştirir, böylece captchafox-wrapper gibi bir sınıfa sahip sarmalayıcı bir öğe yanlışlıkla seçilmez. Son yedek yol, render çağrısına satır içinde verilen bir anahtarı okur. Paketlenmiş bir script dosyasında duran bir anahtar ise HTML’de hiç yer almaz; onu bulmanın yolu DevTools’tur. Kapsayıcı yoksa kod sayfadaki ilk formu alır. Sayfada ayrıca bir arama kutusu ya da ikinci bir form varsa, kayıt formunu bunun yerine id’sine veya action değerine göre seçin.

2. Adım: captchafox çağrısı

Node.js ile CaptchaFox çözmek için tek bir metoda ihtiyacınız var. Metot sitekey’i, sayfa URL’sini ve isteğe bağlı bir seçenekler nesnesini alır; standart widget için ilk ikisi yeterlidir.

import { CapSkip } from "capskip";

const solver = new CapSkip({ host: "127.0.0.1", port: 8080 });
// Copied from the script tag on MAM pages.
const MAM_PACKAGE = "https://s.uicdn.com/mampkg/@mamdev/core.frontend.libs.captchafox/";

const result = await solver.captchafox(sitekey, PAGE_URL, {
  // undefined is dropped, so the standard widget sends nothing extra.
  apiServer: mamSrc ? MAM_PACKAGE : undefined,
});

console.log(result.token.slice(0, 24));   // goes in cf-captcha-response
console.log(result.userAgent);            // the browser that minted it

result.token ve result.code aynı dizeyi tutar; result.captchaId ise CapSkip’in bu işe verdiği id’dir. result.userAgent, token’ı üreten tarayıcının kimliğidir; bu tarayıcı CapSkip’in kendi tarayıcısıdır, sizin gönderdiğiniz herhangi bir şey değildir. Bu değer yalnızca çözüm bir user agent bildirdiğinde ayarlanır, bu yüzden kullanmadan önce kontrol edin.

Sayfa URL’si, widget’ın gerçekten çalıştığı sayfa olmalıdır. CaptchaFox her anahtarı izin verilen alan adlarından oluşan bir listeye kaydeder ve herhangi bir şey vermeden önce host’u kontrol eder. Başka herhangi bir alan adındaki bir sayfa URL’si her denemede reddedilir; bu yüzden kısaltılmış bir bağlantı, bir arama sonucu ya da başka bir alan adından gelen bir yönlendirme işe yaramaz.

Metodun kabul ettiği seçenekler

apiServer, çözülecek widget derlemesini belirten api_server seçeneğinin takma adıdır. Metot, değeri undefined veya null olan her seçeneği çıkarır; yukarıdaki satırın bu seçeneği her çağrıda verebilmesinin nedeni budur. Metot ayrıca type ve uri anahtarlarına sahip bir proxy nesnesini ve useragent seçeneğini de alır; useragent kabul edilir ama bilinçli olarak uygulanmaz, çünkü CapSkip kendi kimliğine sahip gerçek bir tarayıcıda çözer. Saniye cinsinden verilen çağrı başına bir timeout, yalnızca o çözüm için istemcinin recaptchaTimeout değerinin yerini alır. Yoklama aralığının üst sınırı da çağrı başına ayarlanabilir, ama yalnızca polling_interval olarak: camelCase yazılan pollingInterval constructor’a aittir ve çağrı başına verildiğinde ValidationException fırlatır. Boş bir sitekey veya URL, bilinmeyen bir seçenek ve HTTP, HTTPS, SOCKS5 ya da SOCKS5H dışında bir proxy türü de, makinenizden daha hiçbir istek çıkmadan ValidationException fırlatır.

TypeScript’te pakette gelen türler token alanını hâlâ isteğe bağlı ve ALTCHA için düşünülmüş olarak tanımlar; bu yüzden strict modda result.token üzerinde bir non-null assertion gerekir. Değer her CaptchaFox çözümünde bulunur.

3. Adım: token’ı üreten user agent ile gönderin

Node.js ile CaptchaFox çözerken sitenin token’ı kabul edip etmeyeceğine karar veren adım budur. Varsayılan ayarlarda Node’un fetch’i, hem Node 20’de hem de Node 25’te, içinde yalnızca node kelimesi bulunan bir User-Agent başlığı gönderir. Bu, token’ı üreten tarayıcı değildir; bu yüzden dönen değeri, token’ı taşıyan isteğe kopyalayın:

// The form's own fields, hidden CSRF token included.
const body = new URLSearchParams(
  form.serializeArray().map((f) => [f.name, f.value]),
);
body.set("email", "YOUR_EMAIL");
body.set("cf-captcha-response", result.token);

const headers = {
  cookie: [...jar].map(([k, v]) => `${k}=${v}`).join("; "),
  // Browsers send the page as Referer; strict servers want one.
  referer: PAGE_URL,
};
// Without this line, fetch announces itself as user-agent: node.
if (result.userAgent) headers["user-agent"] = result.userAgent;

const res = await fetch(new URL(form.attr("action") || PAGE_URL, PAGE_URL), {
  method: "POST",
  headers,
  body,
});
console.log(res.status);

serializeArray, gizli CSRF token’ı ve işaretli her onay kutusu dahil, bir tarayıcının göndereceği alanları toplar; böylece onları tek tek adlandırmanız gerekmez. Gönder düğmesini ise dışarıda bırakır; bu yüzden sunucu düğmenin adını kontrol ediyorsa onu body.set ile ekleyin. Referer da çerez kadar önemlidir. fetch ne Referer ne de Origin gönderir ve Django dahil bazı framework’ler, doğru çerez ve token olsa bile ikisi de bulunmayan bir HTTPS form gönderimini reddeder.

İki kural daha, CaptchaFox’un token’ı site tarafında nasıl kontrol ettiğinden doğar. Her token yalnızca bir kez ve kısa bir süre için doğrulanır; bu yüzden hazır olduğunuzda çözün ve hemen gönderin. Ayrıca token’ı opak kabul edin: asla kırpmayın ya da yeniden kodlamayın. Bazı siteler token’ı kendi script’lerinden bir JSON gövdesi içinde gönderir; bu yüzden DevTools açıkken formu bir kez elle gönderin ve sayfanın gönderdiğini taklit edin. CaptchaFox’un başlangıç dokümantasyonu widget işaretlemesini ve sunucu tarafındaki kontrolü gösterir.

4. Adım: yeniden denemeler, challenge türleri ve zaman aşımları

CaptchaFox’un hangi challenge’ı çıkaracağını siz seçmezsiniz. Çözümlerin çoğunda hiçbir challenge çıkmaz, çünkü tarayıcı kanıtları tek başına yeterli olur; bir kaydırmalı bulmaca çıktığında ise CapSkip onu genellikle tamamlar. Görsel seçme ve ses challenge’ları nadirdir ve çözülmez: zaman aşımının sonunda değil, saniyeler içinde, mesajında ERROR_CAPTCHA_UNSOLVABLE geçen bir ApiException olarak geri dönerler. Yeni bir deneme genellikle başka bir challenge getirir, bu yüzden yeniden denemeye değer; bunu CapSkip’te ya da kendi kodunuzda yapabilirsiniz.

import { ApiException } from "capskip";

async function solveCaptchaFox(sitekey, url, options = {}, attempts = 3) {
  for (let attempt = 1; ; attempt++) {
    try {
      return await solver.captchafox(sitekey, url, options);
    } catch (err) {
      // Select, audio and unreadable slide draws come back unsolvable;
      // redraw. Anything else, such as a wrong API key, is final.
      const redraw = err instanceof ApiException && err.message.includes("UNSOLVABLE");
      if (!redraw || attempt === attempts) throw err;
    }
  }
}

ApiException mesajı CapSkip’ten gelen ham yanıttır; bu yüzden kontrol, hata kodunu doğrudan bu mesajdan okur. Tek pürüz şu: sitenin reddettiği bir anahtar da (örneğin yanlış alan adındaki bir anahtar) çözülemez olarak görünür, bu yüzden o da yeniden denenir. Böyle bir anahtar her denemede saniyeler içinde başarısız olur ve hiçbir zaman başarılı olmaz; onu ele veren işaret de budur. Diğer yol, CapSkip ayarlarının CaptchaFox satırındaki Retries ayarıdır. 0 ile 3 arasında bir değer alır ve varsayılanı 0’dır. Değeri yükseltirseniz CapSkip desteklenmeyen challenge’ları, süresi dolan denemeleri ve tarayıcı hatalarını kendi başına yeniden dener, ama reddedilen bir anahtarı asla yeniden denemez.

captchafox, istemcinin varsayılanı 300 saniye olan recaptchaTimeout değeriyle yoklama yapar, çünkü bu gerçek bir tarayıcı oturumudur. CapSkip de kendi zamanlayıcısını çalıştırır: bir görev, 10 CaptchaFox thread’inden (Max. Threads) biri için en fazla 250 saniye (Wait Timeout) bekleyebilir ve tek bir deneme 150 saniye (Row Timeout) alır. Boş bir thread varsa başarısız bir deneme, SDK’nın 300 saniyesi dolmadan çok önce size bir ApiException olarak ulaşır. Uzun bir kuyruktan sonra ise SDK önce kendi sınırına ulaşabilir ve CapSkip hâlâ çalışırken TimeoutException fırlatabilir. Bu yüzden çok sayıda çözümü kuyruğa aldığınızda ya da Retries değerini yükselttiğinizde daha uzun bir timeout verin, çünkü her yeniden deneme bir Row Timeout daha ekleyebilir. SDK bağlantı hatalarında da durmadan yoklamaya devam eder; bu yüzden CapSkip çözümün ortasında durursa çağrı NetworkException ile değil, TimeoutException ile sona erer.

Tam çalışan örnek

İşte çalıştırmanın tamamı tek bir dosyada. signUp sayfayı çeker, anahtarı okur, yeniden denemelerle çözer ve formu çerezleriyle, bir Referer ile ve token’ı üreten user agent ile gönderir.

// npm install capskip cheerio
// signup.mjs: run with node signup.mjs
import * as cheerio from "cheerio";
import {
  CapSkip, ApiException, CapSkipError, TimeoutException, ValidationException,
} from "capskip";

const PAGE_URL = "https://example.com/signup";
// Copied from the script tag on MAM pages.
const MAM_PACKAGE = "https://s.uicdn.com/mampkg/@mamdev/core.frontend.libs.captchafox/";

const solver = new CapSkip({
  apiKey: process.env.CAPSKIP_API_KEY ?? "capskip",
  host: process.env.CAPSKIP_HOST ?? "127.0.0.1",
  port: Number(process.env.CAPSKIP_PORT ?? 8080),
});

async function solveCaptchaFox(sitekey, url, options = {}, attempts = 3) {
  for (let attempt = 1; ; attempt++) {
    try {
      return await solver.captchafox(sitekey, url, options);
    } catch (err) {
      // Select, audio and unreadable slide draws come back unsolvable.
      const redraw = err instanceof ApiException && err.message.includes("UNSOLVABLE");
      if (!redraw || attempt === attempts) throw err;
      console.log(`attempt ${attempt}: ${err.message}`);
    }
  }
}

async function signUp(pageUrl, email) {
  // One jar per run, so runs side by side never share a session.
  const jar = new Map();
  const page = await fetch(pageUrl);
  for (const line of page.headers.getSetCookie()) {
    const pair = line.split(";")[0];
    const eq = pair.indexOf("=");
    jar.set(pair.slice(0, eq).trim(), pair.slice(eq + 1).trim());
  }
  const html = await page.text();
  const $ = cheerio.load(html);

  const widget = $(".captchafox").first();
  const mamSrc = $('script[src*="mampkg/@mamdev/core.frontend.libs.captchafox"]').attr("src");
  const sitekey = widget.attr("data-sitekey")
    ?? (mamSrc && new URL(mamSrc, pageUrl).searchParams.get("key"))
    ?? html.match(/captchafox\.render\([\s\S]{0,300}?sitekey\s*:\s*["']([^"']+)/)?.[1];
  if (!sitekey) throw new Error("No sitekey in the HTML; find it in DevTools.");
  const form = widget.length ? widget.closest("form") : $("form").first();

  const result = await solveCaptchaFox(sitekey, pageUrl, {
    apiServer: mamSrc ? MAM_PACKAGE : undefined,
  });

  const body = new URLSearchParams(form.serializeArray().map((f) => [f.name, f.value]));
  body.set("email", email);
  body.set("cf-captcha-response", result.token);
  const headers = {
    cookie: [...jar].map(([k, v]) => `${k}=${v}`).join("; "),
    referer: pageUrl,
  };
  if (result.userAgent) headers["user-agent"] = result.userAgent;

  const action = new URL(form.attr("action") || pageUrl, pageUrl);
  return fetch(action, { method: "POST", headers, body });
}

try {
  const res = await signUp(PAGE_URL, "YOUR_EMAIL");
  console.log(res.status, (await res.text()).slice(0, 80));
} catch (err) {
  if (err instanceof ValidationException) console.error(`not sent: ${err.message}`);
  else if (err instanceof TimeoutException) console.error("gave up after recaptchaTimeout");
  else if (err instanceof CapSkipError) console.error(`solve failed: ${err.name}: ${err.message}`);
  else throw err;
  process.exitCode = 1;
}

Her çalıştırma saniyeler içinde başarısız oluyorsa her şeyden önce sayfa URL’sini kontrol edin, çünkü kayıtlı alan adlarının dışında kullanılan bir anahtar her seferinde aynı şekilde başarısız olur. Sitekey kontrolü hata fırlatıyorsa sayfa widget’ı paketlenmiş bir script’ten oluşturuyordur ve anahtar, 1. adımda anlatıldığı gibi Network sekmesindedir. Bu metodun arkasındaki ham endpoint şurada belgelenmiştir: API referansının CaptchaFox bölümü.

Birçok kayıt işlemini yan yana çalıştırmak

Node’da her CapSkip metodu bir Promise döndürür ve AsyncCapSkip aynı sınıfın yalnızca başka bir adıdır; dolayısıyla çözümleri yan yana çalıştırmak sade JavaScript’tir. İhtiyacınız olan şey bir üst sınırdır. CapSkip varsayılan olarak aynı anda 10 CaptchaFox çözümü çalıştırır ve geri kalanları boş bir thread için bekletir; bu yüzden aynı anda on çağrıyı işlemde tutan küçük bir havuz buna uyar. Onu tam örneğin sonundaki try bloğunun yerine koyun:

// At most `limit` calls in flight; a failure becomes that item's Error.
async function mapLimited(items, limit, fn) {
  const results = new Array(items.length);
  let next = 0;
  async function worker() {
    while (next < items.length) {
      const i = next++;
      results[i] = await fn(items[i]).catch((err) => err);
    }
  }
  await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
  return results;
}

const emails = ["YOUR_EMAIL_1", "YOUR_EMAIL_2", "YOUR_EMAIL_3"];
const results = await mapLimited(emails, 10, (email) => signUp(PAGE_URL, email));
for (const r of results) console.log(r instanceof Error ? r.message : r.status);

signUp, tam örnekteki fonksiyondur. Her çağrıda kendi cookie jar’ını oluşturur ve onu paralel çalışmada güvenli kılan da budur: on çalıştırmanın paylaştığı tek bir cookie jar, onların oturumlarını ve CSRF token’larını birbirine karıştırırdı. Ayrıca her token’ı, gönderim yapılana kadar kendi user agent’ıyla yan yana tutar. Daha büyük bir havuz için CapSkip’in CaptchaFox ayarlarında Max. Threads değerini yükseltin. CaptchaFox ayrıca yalnızca tarayıcıyı değil ağı da puanlar; bu yüzden tek bir adresten gelen çok sayıda çözüm, uzun bir çalışma boyunca challenge oranını yükseltir. Proxy’leri aynı satırdaki Configure Proxies düğmesiyle ayarlayın ya da her çağrıda bir proxy nesnesi verin.

Çözücüyü başka bir makinede çalıştırmak

Betik ve CapSkip aynı Windows bilgisayarı paylaştığı sürece 127.0.0.1 doğru adrestir. Node kodu bir VPS’e, bir konteynere, bir CI runner’a ya da bir serverless fonksiyona taşındığında loopback yanlış makineyi gösterir ve ilk çözüm ECONNREFUSED ile bir NetworkException fırlatır. CapSkip’i Server moduna alın; o zaman ağ adresinizi veya genel IP’nizi dinler, böylece bunların hepsi onu aynı API üzerinden çağırabilir. Rota internetten geçiyorsa statik bir genel IP kullanın, API anahtarı doğrulamasını açın ve bir Windows Firewall kuralıyla portu yalnızca beklediğiniz adreslerle sınırlayın. Çözücü hâlâ sizin kendi Windows makinenizdir ve çözüm başına ücretlendirme hâlâ yoktur.

İstemci ortam değişkenlerini kendiliğinden okumaz. Tam örnekte olduğu gibi CAPSKIP_HOST, CAPSKIP_PORT ve CAPSKIP_API_KEY değerlerini kodunuzda okuyup constructor’a verin; böylece aynı betik hem masanızda hem de bir sunucuda çalışır.

Sık görülen hatalar ve anlamları

GördüğünüzNedenDüzeltme
Site, CapSkip’in çözüldü olarak döndürdüğü bir token’ı reddediyorGönderim, token’ı üreten tarayıcı olarak değil, fetch’in varsayılanı olan user-agent: node ile gittiO istekte User-Agent başlığı olarak result.userAgent değerini gönderin
User agent eşleştiği hâlde reddediliyorSayfa MAM paketini yüklüyor ama çözümde varsayılan widget kullanıldı ya da tam tersiScript etiketini okuyun ve apiServer değerini ona göre ayarlayın
Token ve user agent geçerli olduğu hâlde gönderimde 403 hatasıOturum çerezi gönderilmedi, bu yüzden CSRF alanı artık eşleşmiyor ya da gönderimde Referer yoktuSayfa isteğinden gelen çerezleri taşıyın ve sayfa URL’sini Referer olarak gönderin
result.userAgent değeri undefinedÇözüm bir user agent bildirmedi, bu yüzden fetch kendi user agent’ını gönderiyorif kontrolünü koruyun; site node değerini reddediyorsa güncel bir masaüstü tarayıcı user agent’ını kendiniz gönderin
Tek bir anahtar için her seferinde saniyeler içinde gelen bir ApiExceptionSayfa URL’si, anahtarın kayıtlı olduğu alan adlarının dışında ya da anahtarın kendisi yanlışBir yönlendirmeyi ya da arama sonucunu değil, widget’ın çalıştığı sayfayı gönderin ve anahtarı yeniden kontrol edin
Ara sıra gelen, ERROR_CAPTCHA_UNSOLVABLE içeren bir ApiExceptionCaptchaFox bir görsel seçme veya ses challenge’ı ya da CapSkip’in okuyamadığı bir kaydırmalı bulmaca çıkardıKodda yeniden deneyin ya da CapSkip’in CaptchaFox ayarlarında Retries değerini yükseltin
Bir kez çalışan token ikinci seferde başarısız oluyorHer token yalnızca bir kez doğrulanır ve süresi çabuk dolarHer gönderim için yeni bir token çözün ve hemen gönderin
Daha hiçbir şey gönderilmeden ValidationExceptionBoş bir sitekey veya URL, metodun kabul etmediği bir seçenek (örneğin çağrı başına verilen pollingInterval) ya da CapSkip’in kabul etmediği bir proxy türüSitekey’in bulunduğunu kontrol edin ve mesajda adı geçen seçeneği düzeltin ya da çıkarın
Beş dakika sonra TimeoutExceptionBoş bir CaptchaFox thread’ini bekleme süresi ile çözümün kendisi toplamda SDK’nın 300 saniyesini aştı ya da CapSkip çözümün ortasında durduHavuzu Max. Threads değeriyle sınırlayın ya da o çağrı için daha uzun bir timeout verin
İlk çağrıda ECONNREFUSED veya ETIMEDOUT ile NetworkExceptionCapSkip çalışmıyor, host veya port yanlış ya da bir güvenlik duvarı bağlantıyı düşürüyorCapSkip’i başlatın, ardından Local modunda mı yoksa Server modunda mı olması gerektiğini kontrol edin

FAQ

axios veya got user agent sorununu önler mi?

Hayır. Yalnızca adı değiştirirler. axios, axios ve ardından sürüm numarasını gönderir; got ise got ve ardından GitHub deposunun adresini gönderir. Siz öyle ayarlamadıkça ikisi de çerez saklamaz ya da Referer göndermez; bu yüzden aynı üç başlık burada da geçerlidir. İstemci hangisi olursa olsun, token’ı taşıyan istekteki user agent’ı result.userAgent değerinden ayarlayın.

Token’ı bunun yerine Puppeteer veya Playwright’ta kullanabilir miyim?

Evet, token’ı gönderen sayfa CapSkip’in döndürdüğü user agent ile çalıştığı sürece. Önce çözün, ardından browser.newContext({ userAgent: ua }) ile bir Playwright context’i açın ya da Puppeteer’da sayfa yüklenmeden önce page.setUserAgent(ua) çağırın. Formu yükleyin, token’ı cf-captcha-response alanına yazın ve gönderin. Otomasyonunuzun başka hiçbir şey için tarayıcıya ihtiyacı yoksa yukarıdaki fetch yolu daha hafiftir.

Bunun Python sürümünden farkı nedir?

Çağrı ve kurallar aynıdır, asıl tuzak da aynıdır: HTTP istemcisi user agent olarak kendi adını gönderir. Python’da bu ad python-requests veya python-httpx olur ve bir requests.Session çerezleri sizin yerinize saklar. Node’da ise bu ad node olur ve çerezleri kendiniz taşırsınız. Python tarafı şurada ele alınıyor: Python ile CaptchaFox çözme rehberi.

Kısa özet

Node.js ile CaptchaFox çözmek için sayfayı çekin ve çerezlerini saklayın, sitekey’i captchafox kapsayıcısından, render çağrısından ya da MAM script’inden okuyun ve sayfanın hangi derlemeyi yüklediğini not edin. solver.captchafox() metodunu sitekey ve gerçek sayfa URL’siyle çağırın; apiServer seçeneğini yalnızca MAM sayfaları için ekleyin. result.token değerini sayfanın çerezleriyle, Referer olarak sayfanın adresiyle ve User-Agent başlığı olarak result.userAgent ile birlikte cf-captcha-response alanında bir kez ve hemen gönderin. Çözülemeyen challenge’ları yeniden deneyin, aynı anda Max. Threads değerinden (varsayılanı 10) fazla çözümü işlemde tutmayın ve betik çözücünün makinesinden ayrıldığında Server moduna geçin.

Bu türün genellikle ihtiyaç duyduğu tek yeniden deneme, yeni bir challenge çıkarılmasıdır ve kendi makinenizde çalışan bir sınırsız captcha çözücü ile her yeni challenge, faturalanan bir çözüm daha yerine yalnızca birkaç saniyeye mal olur.