Node.js ile hCaptcha Enterprise Nasıl Çözülür (capskip SDK)

hcaptcha enterprise in node.js - How to Solve hCaptcha Enterprise in Node.js (capskip SDK)

Node.js’te hCaptcha Enterprise çözmek için siteden yeni bir rqdata alın ve onu capskip paketinin hcaptcha() metoduna, sitekey ve sayfa URL’siyle birlikte data seçeneği olarak verin. Metot görevi CapSkip’e gönderir, token hazır olana kadar yoklar ve onu döndürür. Sonra token’ı, sonuçtaki User-Agent ile forma gönderin. CapSkip belgeleri, sitenin her rqdata değerini tek bir challenge için verdiğini ve kısa sürede geçerliliğini yitirdiğini söyler; bu yüzden her görev ve her yeniden deneme için yenisi gerekir. Aşağıdaki kod CapSkip hCaptcha çözücüsü ile konuşur. O, kendi Windows bilgisayarınızda çalışır ve çözüm başına ücret almaz.

Neye ihtiyacınız var

  • Windows makinenize kurulu CapSkip 4.0.0 veya üzeri. Bu sürüm, Enterprise dahil hCaptcha çözmeyi hem burada kullanılan in.php biçiminde hem de createTask JSON biçiminde ekledi.
  • Node.js 18 veya üzeri ve capskip paketi, 1.6.0 veya sonrası; hcaptcha metodu olan ilk sürüm. Paket Node.js 18’i alt sınır olarak bildirir ve kendi bağımlılığı yoktur; form gönderimi yerleşik fetch’i kullanır. Kodu yalnızca 20.11.1, 24.22.0 ve 25.2.1 üzerinde çalıştırdım.
  • Sahibi olduğunuz ya da otomatikleştirmenize izin verilen, hCaptcha widget’ı gösteren bir site ve o widget’ın sitekey’i.
  • Script’ten CapSkip’e giden bir yol. Local modu CapSkip’i 127.0.0.1 üzerinde tutar, yalnızca o tek cihazdan erişilebilir. Server modu ağınızı veya genel IP’nizi de dinlemesini sağlar, böylece bir Windows VPS’teki script, başka bir bilgisayar ya da barındırılan bir platform da onu kullanabilir; bu mod CapSkip’in yönetici olarak çalışmasını gerektirir. Modu şuradan seçersiniz: bağlantı ayarları.

Durum şöyle: kodu capskip 1.6.0 ile kendi yazdığım iki mock sunucuya karşı çalıştırdım; biri CapSkip’in, diğeri her rqdata değerini bir kez kabul eden bir Enterprise sitenin yerini tutuyor. Bu kurallar benimdir ve CapSkip belgelerinden ve paket kaynağından alınmıştır. Okuduğum herkese açık hCaptcha belge sayfalarının hiçbiri rqdata’yı anlatmıyor, bu yüzden buradaki her rqdata bilgisi CapSkip belgelerinden gelir. Gerçek bir çözüm yapılmadı, bu yüzden birinin ne kadar sürdüğünü ya da gerçek bir Enterprise sitenin nasıl davrandığını söyleyemem.

1. Adım: sitekey’i, invisible bayrağını ve rqdata değerini bulun

Boş bir klasörde npm install capskip komutunu çalıştırın. Sonra 1. ile 4. Adımların bloklarını, gösterilen sırayla, o klasördeki hcaptcha-demo.js adlı tek bir dosyaya kopyalayın. 2. Adım’ın sonuna test satırını eklemediğiniz sürece 4. Adım’a kadar hiçbir şey çalışmaz. recaptchaTimeout seçeneği, SDK’nın hCaptcha için saniye cinsinden yoklama sınırıdır. Varsayılanı 300 saniyedir; daha kısa olan 120 saniyeyi kendim seçtim.

// npm install capskip
const { CapSkip, ApiException } = require("capskip");

const CAPSKIP = { host: "127.0.0.1", port: 8080 }; // Local mode; Server mode: your server
const SITE = "https://www.example.com"; // a site you may automate
const PAGE_URL = `${SITE}/login`; // the page the hCaptcha widget is on
// The SDK's default key. Use your own if API Key Validation is on in CapSkip.
const API_KEY = "capskip";
const PROXY = null; // for example "203.0.113.10:8080"; null means no proxy

const solver = new CapSkip({
  ...CAPSKIP,
  apiKey: API_KEY,
  recaptchaTimeout: 120, // poll limit in seconds for hCaptcha; the default is 300
});

Sitekey genellikle widget kapsayıcısında data-sitekey olarak durur. Widget’ı bir script oluşturuyorsa hcaptcha.render() çağrısındaki sitekey seçeneğine ya da hCaptcha iframe adresindeki sitekey= parametresine bakın. hCaptcha invisible widget kılavuzu invisible bir widget’ı data-size değerinin invisible olarak ayarlanmasıyla tanımlar ve CapSkip belgeleri böyle bir widget için invisible=1 göndermenizi söyler.

rqdata sıra dışı olandır. CapSkip belgeleri, bazı Enterprise sitelerinin çalışmadan önce hcaptcha.setData() ile widget’a bir rqdata değeri geçirdiğini ve sayfa bunu yapıyorsa değeri data olarak göndermeniz gerektiğini söyler. Yapmıyorsa data alanı göndermeyin. Değerin nereden geldiği sitenin tercihidir. Sayfa HTML’inde olabilir ya da sayfanın yaptığı bir istekten dönebilir; bu yüzden sayfa script’lerinde onu ayarlayan çağrıyı arayın ve dizeyi izleyin. Bunu gerçek bir Enterprise sitesinde denemedim ve aşağıdaki fonksiyon mock’umun sunduğu yolu kullanır.

// Ask the site for a new challenge. The route and the field names are the
// site's choice; these are the ones in my test mock, so adapt them.
// If the sitekey is fixed in the page, return it as a constant here.
// If the site puts the values in the page HTML, fetch PAGE_URL and
// extract them here instead.
async function getChallenge() {
  const resp = await fetch(`${SITE}/api/challenge`);
  if (!resp.ok) throw new Error(`challenge failed: HTTP ${resp.status}`);
  const { sitekey, rqdata, invisible } = await resp.json();
  return { sitekey, rqdata, invisible: Boolean(invisible) };
}

2. Adım: görevi gönderin ve token’ı alın

Tek bir çağrı görevi gönderir ve sonucu yoklar. hcaptcha() metodu sitekey’i, sayfa URL’sini ve bir seçenekler nesnesini alır: data rqdata değeridir, invisible bir invisible widget için true olur ve proxy çözüm için kullanılan proxy’dir. SDK bunları method=hcaptcha ile form alanları olarak /in.php adresine gönderir ve invisible değerini 1 olarak yollar. Hiçbir userAgent seçeneği göndermez: belgeler, CapSkip’in bu seçeneği yalnızca kendi çözdüğü tarayıcıyla eşleştiğinde kullandığını söyler ve sonuç, token’ı kazanan User-Agent’ı taşır.

async function solve({ sitekey, rqdata, invisible }) {
  const options = {};
  // The Enterprise rqdata, fresh for this task. Skip it if the site has none.
  if (rqdata) options.data = rqdata;
  if (invisible) options.invisible = true; // data-size is invisible
  if (PROXY) options.proxy = PROXY;
  // Submits the task, polls until the token is ready, and returns the result.
  return solver.hcaptcha(sitekey, PAGE_URL, options);
}

SDK /res.php adresini sizin için yoklar. İlk yoklama hemen gider, sonraki beklemeler saniyenin dörtte biriyle başlar, her seferinde ikiye katlanır ve 5 saniyede büyümeyi bırakır. Boş bir gövde hazır değil sayılır: belgeler bunun sonucun zaten okunduğu ya da ID’nin bulunmadığı anlamına geldiğini söyler ve SDK kaynağı CapSkip’in görevi gönderdikten hemen sonra bir tane yolladığını ekler. Sınır geçtiğinde çağrı bir TimeoutException fırlatır.

Bir sonuç bir kez teslim edilir ve SDK hepsini sizin için saklar. code ve token alanları aynı dizeyi taşır. respKey, hCaptcha’nın token ile birlikte widget’a verdiği ikinci değerdir. Belgelere göre çoğu site onu hiç okumaz ve CapSkip hiçbir şey göndermezse SDK onu boş bir dizeye ayarlar. Token’ı kazanan User-Agent için userAgent alanını okuyun.

1. ve 2. Adımları tek başına denemek için son satır olarak getChallenge().then(solve).then(console.log) ekleyin ve node hcaptcha-demo.js çalıştırın. captchaId, code, userAgent, respKey ve token içeren bir nesne görmelisiniz. Sonraki bloğu eklemeden önce o satırı yeniden silin.

3. Adım: token’ı forma verin

Bir tarayıcı widget’ı iki gizli textarea alanını kendiliğinden doldurur: h-captcha-response ve g-recaptcha-response adlı bir yansıma. Bir script’in widget’ı yoktur, bu yüzden bunları form alanları olarak gönderir. CapSkip belgelerine göre bu, her zaman h-captcha-response, formda o alan da varsa g-recaptcha-response ve yanıttaki User-Agent anlamına gelir. Aşağıdaki form bir yer tutucudur, çünkü sitenizin kendi alanları ve kendi yolu vardır.

Token’lar tek kullanımlıktır ve CapSkip belgeleri, verildikten yaklaşık iki dakika sonra sona erdiklerini söyler. hCaptcha’nın kendi belgeleri, expired-input-response hatası için varsayılan olarak 120 saniye verir. Bu yüzden önceden çözmeyin ve token havuzu tutmayın. Her form gönderimi için çözün, sonra gönderin.

async function postForm(solved) {
  const form = new URLSearchParams({
    username: "demo", // the form's own fields
    "h-captcha-response": solved.token,
    // delete the next line if the form has no g-recaptcha-response field
    "g-recaptcha-response": solved.token,
  });
  // Send the User-Agent the reply names, not Node's default one.
  return fetch(PAGE_URL, {
    method: "POST",
    headers: { "User-Agent": solved.userAgent },
    body: form,
  });
}

4. Adım: her denemede yeni bir rqdata ile tam örnek

Son blok her şeyi bir yeniden deneme döngüsüne bağlar. Onu hcaptcha-demo.js dosyasının sonuna ekleyin ve node hcaptcha-demo.js ile başlatın. Her deneme önce getChallenge çağırır, bu yüzden her görev, az önce verilmiş bir rqdata taşır. Döngü yalnızca ERROR_CAPTCHA_UNSOLVABLE kodunu, yani çözülemeyen bir görevin kodunu yeniden dener. CapSkip belgeleri, yeniden göndermenin tekrarlayacağı iki hatayı adlandırır: bir sorguda ERROR_RECAPTCHA_INVALID_SITEKEY, yani hCaptcha sitekey’i o sayfa için reddetti, ve ERROR_PROXY_CONNECT_REFUSED. Döngü bunları ve diğer her hatayı değiştirmeden yeniden fırlatır.

Döngü, site 200 ile 299 dışında bir yanıt verdiğinde de yeniden döner, çünkü reddedilen bir token eski bir rqdata anlamına gelebilir. Bir 403’ün, örneğin bir giriş formunda yanlış parola gibi, başka nedenleri olabilir; bu yüzden denemeler üçte durur.

// ERROR_CAPTCHA_UNSOLVABLE is the one failure where a new task can help.
async function login() {
  for (let attempt = 1; attempt <= 3; attempt += 1) {
    const challenge = await getChallenge(); // a new rqdata for every attempt
    try {
      const solved = await solve(challenge);
      const resp = await postForm(solved);
      if (resp.ok) return resp;
      console.log(`attempt ${attempt}: the site answered HTTP ${resp.status}`);
    } catch (err) {
      // The message is the text of the app's reply: a bare code or small JSON.
      const unsolvable = err instanceof ApiException
        && err.message.includes("ERROR_CAPTCHA_UNSOLVABLE");
      if (!unsolvable) throw err;
      console.log(`attempt ${attempt}: ERROR_CAPTCHA_UNSOLVABLE`);
    }
  }
  throw new Error("hCaptcha not passed in 3 attempts");
}

login()
  .then(async (resp) => console.log(resp.status, await resp.text()))
  .catch((err) => {
    console.error(`${err.name}: ${err.message}`);
    if (err.cause) console.error(err.cause.code); // for example ECONNREFUSED
    process.exitCode = 1;
  });

SDK kendi üç hatasını ekler. ValidationException, çağrıyı hiçbir şey göndermeden reddettiği anlamına gelir: boş bir sitekey, mutlak http veya https olmayan bir sayfa URL’si, hatalı bir invisible değeri ya da CapSkip hCaptcha API’sinin almadığı bir seçenek, örneğin 2Captcha’nın domain seçeneği. Görev gönderilirken NetworkException, CapSkip adresinde hiçbir şeyin yanıt vermediği, TimeoutException ise yoklama sınırının geçtiği anlamına gelir. Yeni bir görev bunların hiçbirini değiştirmez, bu yüzden döngü onları yeniden fırlatır. ApiException iletisi uygulamanın yanıtını metin olarak taşır, bu yüzden döngü onu includes() ile eşleştirir.

Script’in mock’lara karşı yaptığı şey burada, Node.js 24.22.0 üzerinde capskip 1.6.0 ile. Node.js 20.11.1 ve 25.2.1 her durumu aynı şekilde, aynı çıkış kodlarıyla bitirdi. Test düzeneği yalnızca adresleri ve zaman aşımı satırlarında yoklama sınırını değiştirdi.

Mock ayarıScript ne yaptı
Enterprise site; mock üçüncü yoklamada ya da görevden 20 saniye sonra hazırHer iki durumda da bir görev ve 200 durumu. İlkinde yoklamalar yaklaşık 0, 0,3 ve 0,8 saniyede geldi. İkincisinde üç çalışma zamanında da yaklaşık 0, 0,3, 0,8, 1,8, 3,8, 7,8, 12,8, 17,8 ve 22,8 saniyede geldi; yani token, hazır olduktan 2,8 saniye sonra script’e ulaştı
Invisible site; rqdata vermeyen sitein.php ilk durumda invisible=1 aldı, ikincisinde data alanı almadı ve iki form gönderimi de geçti
ERROR_CAPTCHA_UNSOLVABLE bir çalıştırmada iki, başka birinde üç kezİki başarısızlık: üçüncü görevde, üç farklı rqdata değeriyle 200 durumu. Üç başarısızlık: “hCaptcha not passed in 3 attempts” Error’ı ve çıkış kodu 1
Mock site ilk token’ı reddediyor“attempt 1: the site answered HTTP 403”, ardından yeni bir rqdata ile ikinci bir görev ve 200 durumu
İkinci bir giriş için yeniden kullanılan önbellekteki challenge (ilki geçti); data alanı çıkarılmış; yanıttaki User-Agent olmadan gönderilen formBu denemelerin her biri mock siteden 403 aldı ve her çalıştırma “hCaptcha not passed in 3 attempts” Error’ı ile bitti. Bunlar benim mock’umun kuralları, gerçek bir sitenin değil
Boş sitekey, ftp pageurl, invisible değeri maybe sözcüğüne ayarlı, domain seçeneği; proxy olmayan bir proxy dizesi, CapSkip’in tanımadığı bir anahtar, görev türü reddedildiİlk dört durumda ValidationException, in.php’ye hiç görev gönderilmeden. Diğerlerinde ERROR_PROXY_FORMAT, ERROR_KEY_DOES_NOT_EXIST ve ERROR_TASK_NOT_SUPPORTED ile ApiException, her biri bir görevden sonra. Her seferinde çıkış kodu 1
ERROR_PROXY_CONNECT_REFUSED veya ERROR_RECAPTCHA_INVALID_SITEKEY yanıtı veren sorgularYalnızca bir görev. Script ilk hatada durdu
203.0.113.10:8080 ya da user:[email protected]:8080 proxy’si; hiç hazır olmayan mock (sınır 1,5 saniyeye indirildi); CapSkip adresinde hiçbir işlem yokin.php, proxy dizesini değiştirilmeden, proxytype HTTP ile aldı ve çalıştırma geçti; TimeoutException: timeout 1.5 exceeded; NetworkException: connect ECONNREFUSED, sonraki satırda yine ECONNREFUSED ve hiç görev yok
Mock 120 saniyelik sınırla hiç hazır olmuyor; bir çözüm sırasında kapanan mock süreci (sınır 4 saniyeye düşürüldü)Son yoklama 118. saniyede geldi, TimeoutException yaklaşık 123. saniyede. Mock öldükten sonra SDK yoklamaya devam etti ve bir bağlantı hatasıyla değil, TimeoutException ile bitti

Yaygın hatalar

HataNedenDüzeltme
ERROR_WRONG_USER_KEY ya da ERROR_KEY_DOES_NOT_EXIST ile ApiExceptionCapSkip’te API Key Validation açık ve API_KEY anahtarlarından biri değil.API_KEY değerini CapSkip’ten bir anahtara ayarlayın.
ERROR_TASK_NOT_SUPPORTED ile ApiExceptionCapSkip görev türünü reddediyor. 4.0.0 öncesi bir sürüm nedenlerden biridir4.0.0 veya üzerine güncelleyin
ERROR_RECAPTCHA_INVALID_SITEKEY ile ApiExceptionhCaptcha sitekey’i o sayfa için reddetti. Boş bir sitekey buraya hiç gelmez, çünkü SDK onu önce reddederSitekey ve pageurl değerlerini sayfayla karşılaştırarak kontrol edin
ValidationExceptionSDK çağrıyı hiçbir şey göndermeden reddetti ve iletisi sorunu adıyla söylüyorÇağrıyı düzeltin
ERROR_PROXY_FORMAT ile ApiExceptionProxy dizesi, CapSkip’in kabul etmediği bir biçimdeIP:PORT, LOGIN:PASSWORD@IP:PORT veya IP:PORT:LOGIN:PASSWORD kullanın
ApiException ile ERROR_PROXY_CONNECT_REFUSEDCapSkip, hedefe proxy üzerinden ulaşamadıProxy’yi tek başına deneyin, giriş bilgisini ve türü kontrol edin, script’i yeniden çalıştırın
ERROR_CAPTCHA_UNSOLVABLE içeren ApiExceptionGörev çözülemediYeni bir rqdata alın ve yeni bir görev gönderin. Döngü bunu yapar
TimeoutException: timeout 120 exceededGörev script’in sınırında hâlâ çalışıyordu ya da ID bilinmiyordu veya sonucu zaten okunmuştu (ikisi de boş gövde olarak döner)CapSkip’teki Monitor sekmesine bakın, sonra script’i yeniden çalıştırın
NetworkException: connect ECONNREFUSEDCAPSKIP adresinde yanıt veren yok: CapSkip durmuş ya da host veya port yanlış. Ondan sonraki satır nedeni gösterir; dinleyen olmayan bir port için ECONNREFUSEDCapSkip’i başlatın, sonra adresi bağlantı ayarlarınızla karşılaştırın
Site, çözülmüş bir token’dan sonra formu reddediyorToken sitenin izin verdiğinden eski, User-Agent ya da adres çözümden farklı, site token’ı riskli olarak puanladı ya da rqdata eskiydi veya yeniden kullanıldı (mock’um bunu zorunlu kılar, belgeler yalnızca hızla sona erdiğini söyler)Çözümden hemen sonra gönderin, yanıttaki userAgent değerini gönderin, her görev için yeni bir rqdata alın ve aşağıdaki proxy notlarına bakın

Proxy’ler ve Server modu

CapSkip hCaptcha için proxy zorlamaz. Belgeler, test için ve ara sıra yapılan çözümler için tek bir adresin yeterli olduğunu söyler, ama hCaptcha tarayıcının yanı sıra bir token’ın geldiği ağı da puanlar ve tek bir IP’den gelen düzenli çözüm akışı, hız sınırlarının tam da yakalamak için kurulduğu şeydir. Yüksek hacimde uygulamada Settings, Captcha types, hCaptcha, Configure Proxies altında bir proxy havuzu yapılandırın. Bir çözümün belirli bir ağdan gelmesini istiyorsanız görevle birlikte bir proxy gönderin; PROXY ayarı bunu yapar. Bir görevle gönderilen proxy her zaman listeye üstün gelir. CapSkip proxy’yi IP:PORT, LOGIN:PASSWORD@IP:PORT ya da IP:PORT:LOGIN:PASSWORD olarak kabul eder. Tek başına bir proxy dizesi proxytype HTTP ile gider. SOCKS5 için proxy’yi, HTTP, HTTPS, SOCKS5 veya SOCKS5H değerlerini alan bir type ve bir uri içeren nesne olarak verin. Mock’a karşı bu, in.php’ye proxytype SOCKS5 olarak ulaştı. Gerçek bir SOCKS5 çözümünü test etmedim.

Ayar yalnızca çözümü taşır. Katı bir site için belgeler formu da aynı adresten göndermenizi söyler, ama Node.js’in yerleşik fetch’inde istek başına proxy seçeneği yoktur; bu yüzden buradaki form gönderimi script’i çalıştıran bilgisayardan çıkar. Form gönderimini bir proxy üzerinden test etmedim.

Server modu yalnızca çözücünün nerede durduğunu değiştirir. CAPSKIP ayarını sunucuya yöneltin; script’in geri kalanı olduğu gibi kalır. Server modu, CapSkip’in yönetici olarak çalışmasını gerektirir ve statik bir genel IP en kararlı uzaktan erişimi sağlar. Çözücü hâlâ kendi donanımınızdır ve çözüm başına ücret yoktur. CapSkip bundan sonra her adresten gelen bağlantıları kabul eder; bu yüzden ona ulaşmaması gerekenler için bir Windows Firewall engelleme kuralı ekleyin, CapSkip’te API Key Validation özelliğini açın ve API_KEY alanını doldurun. Çözüm artık Windows VPS üzerinde çalışır, bu yüzden hCaptcha o makinenin ağını ya da geçirdiğiniz proxy’yi görür.

FAQ

Node.js’te hCaptcha Enterprise neden her seferinde yeni bir rqdata gerektirir?

CapSkip belgeleri, sitenin değeri tek bir challenge için verdiğini ve değerin hızla sona erdiğini söyler; bu yüzden önbellekteki bir değer eski bir değerdir. Eski bir değer, reddedilen bir token için olası nedenlerden biridir ve bu rehberin dışarıda bırakabildiği tek nedendir. Gerçek bir sitenin eski bir değerle nasıl başarısız olduğu okuyabildiğim hiçbir yerde belgelenmemiş; bu yüzden mock’umun reddi yalnızca döngünün nasıl tepki verdiğini gösterir.

Site, CapSkip’in döndürdüğü bir token’ı yine de reddederse ne olur?

Settings içindeki Captcha types altında, hCaptcha satırındaki High score mode ayarına bakın. CapSkip değişiklik günlüğü, 4.0.0 sürümünün onu varsayılan olarak açtığını ve Google Chrome içinde çözdüğünü söyler. Mod kapalıyken ya da Chrome kurulu değilken CapSkip Custom Browser içinde çözer ve Chrome olmadan ayar grileşir. API belgeleri katı siteler için üç alışkanlık daha ekler: iyi bir proxy kullanın, formu aynı adresten gönderin ve yanıtın adlandırdığı User-Agent’ı gönderin.

Barındırılan bir platformda ya da bir VPS’te çalışan bir script’ten CapSkip’i çağırabilir miyim?

Evet, CapSkip Server modundaysa. CAPSKIP ayarını adresine yöneltin; script’in başka bir değişikliğe ihtiyacı yok. Çözümün artık sunucuda çalıştığını unutmayın; site ağa önem veriyorsa göreve bir proxy verin. CapSkip sahip olduğunuz donanımda kalır.

Site size ne çıkarırsa çıkarsın, Node.js’te hCaptcha Enterprise çözmek tek bir döngü olarak kalır: yeni bir rqdata, yeni bir görev, hemen gönderilen bir token. Bunu kendi makinenizde çalışan bir captcha çözücü üzerinden yürütmek, yeniden denemenin çözüm başına ücret taşımadığı anlamına gelir. Daha fazla araç için Node.js CAPTCHA çözücü sayfasınagöz atın. Her parametrenin ayrıntısı için bkz. API belgelerinin hCaptcha bölümü.