Deno’da reCAPTCHA Nasıl Çözülür: İzinler ve Zaman Aşımları

Deno’da reCAPTCHA çözmek için CapSkip Node.js SDK’sını bir npm specifier’ı üzerinden içe aktarın ve çözücünün adresini ortam değişkenlerinden kendiniz okuyun. Ardından script’i yalnızca CapSkip’i ve sitenizi adlandıran izin bayraklarıyla çalıştırın. CapSkip kendi Windows bilgisayarınızda çalışır, dolayısıyla çözüm başına ücret yoktur. Kod kısadır. Zor olan kısım Deno’nun izin modelidir. SDK, engellenen bir çağrıyı ağ hatası olarak bildirir. Sessizleşen bir CapSkip, script’i hata vermeden ve çıkmadan takılı bırakır. Zaman aşımı eklemenin olağan yolu da süreci, tanınan sürenin tamamı boyunca ayakta tutar. Bu rehber bunların her birini ele alır.
Neye ihtiyacınız var
- reCAPTCHA çözücüsü açık hâlde bir Windows bilgisayarında çalışan CapSkip. İlk başlatmayı kurulum kılavuzu adım adım anlatıyor.
- Deno 2. Aşağıdaki her şey, npm’den gelen capskip 1.3.0 ile Windows 11 üzerinde Deno 2.9.6 ile çalıştırıldı ve 2.9.7 ile yeniden denendi.
- Bir PowerShell istemi. Komutlar PowerShell sözdizimini kullanır.
- Bir formda reCAPTCHA v2 onay kutusu bulunan bir sayfa. Örnek, bir CSRF token’ı taşıyan Django tarzı bir forma giriş yapar. Alan adlarını kendi sitenize uyacak şekilde değiştirin.
- Çö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ı.
Aşağıdaki ölçümler, aynı bilgisayardaki sahte (mock) bir CapSkip ve sahte bir giriş sayfasından, gerçek Deno ve gerçek SDK ile alındı. İzin hataları, yoklama takvimi ve takılı kalma davranışı Deno’ya ve SDK’ya aittir, bu yüzden kendi siteniz için de geçerlidir. Çözüm süreleri ile giriş sayfasının kabul ve ret kuralları ise mock’a özgüdür.
1. Adım: Deno’yu kurun ve projeyi oluşturun
Deno’yu resmi yükleyicisiyle ya da winget ile kurun. Deno’nun kurulum sayfası Scoop ve Chocolatey gibi diğer seçenekleri listeler.
# PowerShell: the official installer (or: winget install DenoLand.Deno) irm https://deno.land/install.ps1 | iex deno --version
Ardından bir proje klasörü oluşturun ve başka herhangi bir şeyi çalıştırmadan önce içine bir deno.json koyun. Import map, SDK sürümünü sabitler ve script’te uzun bir npm specifier’ı yerine "capskip" yazmanızı sağlar.
{
"imports": {
"capskip": "npm:[email protected]"
}
}Bu dosya oluşmadan deno add çalıştırmayın. Projenizin üstündeki bir klasörde package.json varsa (bu, bir kullanıcı profilinde yaygındır) Deno projeyi bir Node projesi sayar. O zaman npm:[email protected] import’u Could not find "capskip" in a node_modules folder hatasıyla başarısız olur. Sürümsüz bir import ise orada kurulu olan capskip hangisiyse onu sessizce yükler. Test bilgisayarında bu, daha eski bir 1.0.2 idi. deno.json olmadan deno add çalıştırmak, üstteki o package.json dosyasını bile yeniden yazdı. Kendi klasörünüzdeki bir deno.json, Deno’nun proje kökü olarak sizin klasörünüzü kullanmasını sağlar.
2. Adım: SDK’yı içe aktarın ve ayarları okuyun
2. ile 5. adımlardaki kodu, gösterilen sırayla, solve.js adlı tek bir dosyaya kaydedin. Dosyanın tamamı bu rehberin sonuna doğru yeniden verilir. Deno onu bir ES modülü olarak çalıştırır; bu yüzden SDK README’sindeki require çağrısı burada require is not defined hatasıyla başarısız olur. Adlandırılmış import’u kullanın. Varsayılan import da başarısız olur, çünkü size exports nesnesinin tamamını verir: new CapSkip() çağrısı CapSkip is not a constructor hatası fırlatır.
import { CapSkip } from "capskip";
// The SDK never reads the environment, so read it here and pass it in.
const host = Deno.env.get("CAPSKIP_HOST") ?? "127.0.0.1";
const port = Number(Deno.env.get("CAPSKIP_PORT") ?? 8080);
const apiKey = Deno.env.get("CAPSKIP_API_KEY") ?? "capskip";
const solver = new CapSkip({ host, port, apiKey });
// The login page to solve, passed on the command line.
const pageUrl = Deno.args[0] ?? "https://example.com/login";SDK ortam değişkenlerini kendi başına okumaz, bu yüzden script onları okur ve constructor’a verir. Varsayılan değerler sayesinde dosya hiçbir kurulum yapmadan çalışır. CAPSKIP_API_KEY yalnızca CapSkip’te API key validation’ı açtıysanız önemlidir.
3. Adım: sayfayı çekin ve çerezlerini saklayın
Deno’nun fetch’inde cookie jar yoktur, bu yüzden script bir tane tutar. Her Set-Cookie satırını getSetCookie ile okur. Bunun yerine set-cookie üzerinde headers.get çağırmak, satırları tek bir dizede birleştirir. Bir çerezin Expires tarihi virgül içerir, bu yüzden virgüllerden bölen saf bir yöntem çerezleri yanlış yerlerden keser.
// Deno's fetch keeps no cookies, so collect every Set-Cookie line.
// (headers.get("set-cookie") would glue them into one string.)
const jar = new Map();
/** @param {Response} response */
function keepCookies(response) {
for (const line of response.headers.getSetCookie()) {
const [pair] = line.split(";");
const eq = pair.indexOf("=");
jar.set(pair.slice(0, eq).trim(), pair.slice(eq + 1).trim());
}
}
const cookies = () => Array.from(jar, ([k, v]) => `${k}=${v}`).join("; ");Ardından script giriş sayfasını yükler ve sitekey’i ile CSRF token’ını ondan okur. İki deseni sayfanızın HTML yapısına göre ayarlayın.
const page = await fetch(pageUrl);
keepCookies(page);
const html = await page.text();
// Adjust these two patterns to your page's markup.
const sitekey = html.match(/data-sitekey="([^"]+)"/)?.[1];
const csrf = html.match(/name="csrfmiddlewaretoken" value="([^"]+)"/)?.[1];
if (!sitekey || !csrf) throw new Error("sitekey or CSRF token not found");4. Adım: CapSkip’ten bir token isteyin
İşi tek bir çağrı yapar. Görevi gönderir, cevap için yoklama yapar ve token’ı döndürür. SDK önce hemen yoklar, sonra çeyrek saniye bekler ve bekleme süresini her seferinde ikiye katlar, en fazla 5 saniyeye kadar. CapSkip’in bir saniyede bitirdiği bir çözüm testte yaklaşık 1.8 saniyede geri geldi; Node altında da aynıydı.
// code is typed "string or object" (Capy shares the field), so
// String() keeps deno check quiet.
const { code } = await solver.recaptcha(sitekey, pageUrl);
const token = String(code);Sonuçta bir code alanı vardır ve token odur. SDK’nın tür dosyası onu bir dize ya da bir nesne olarak tanımlar, çünkü bazı CAPTCHA türleri aynı alanda bir nesne döndürür. String() onu sade bir dizeye çevirir. Sonraki bir bölüm bu çağrıya bir zaman aşımı ekler.
5. Adım: formu gönderin ve sonucu kontrol edin
Script, token’ı g-recaptcha-response alanında, diğer form alanlarının yanında gönderir. İki ayrıntı önemlidir. Deno’nun fetch’i Referer göndermez ve HTTPS üzerinden çalışan Django gibi katı bir site, Referer olmayan bir form gönderimini reddeder; bu yüzden script onu ayarlar. Ayrıca fetch çağrısı redirect manual kullanır, böylece 302 yanıtı geri gelir ve yeni oturum çerezi okunabilir. Yönlendirmeleri izleyen varsayılan ayarda 302 üzerindeki çerez kaybolur ve giriş 200 koduyla yeniden formun kendisine döner.
// fetch sends no Referer, and a strict site rejects the post without
// one. redirect "manual" keeps the 302 so we can read its new cookie.
const response = await fetch(pageUrl, {
method: "POST",
redirect: "manual",
headers: { Cookie: cookies(), Referer: pageUrl },
body: new URLSearchParams({
csrfmiddlewaretoken: csrf,
username: "YOUR_USERNAME",
password: "YOUR_PASSWORD",
"g-recaptcha-response": token,
}),
});
keepCookies(response);Reddedilen bir giriş çoğu zaman 200 koduyla yine formu döndürür. Bu yüzden script 302 dışındaki her şeyi başarısızlık sayar, ardından yalnızca giriş yapılmış bir sayfanın gösterdiği bir işaret arar. Welcome back yerine kendi sitenizdeki bir metni koyun. Reddedilen bir giriş için başarı bildiren bir script, hata veren bir script’ten daha kötüdür.
// A good login answers 302 and rotates the session cookie.
if (response.status !== 302) {
const body = await response.text();
throw new Error(`login rejected: ${response.status} ${body}`);
}
const next = new URL(response.headers.get("location") ?? "/", pageUrl);
const home = await fetch(next, { headers: { Cookie: cookies() } });
// Swap "Welcome back" for a marker your own site shows after login.
const ok = (await home.text()).includes("Welcome back");
console.log(ok ? "logged in" : "NOT logged in");
if (!ok) Deno.exit(2);6. Adım: en küçük izin kümesiyle çalıştırın
Deno, siz izin verene kadar ağ, ortam ve dosya erişimini reddeder. Deno’da reCAPTCHA çözmek için bu script’in iki şeye ihtiyacı vardır ve aşağıdaki komut tam olarak onları verir.
deno run ` --allow-env=CAPSKIP_HOST,CAPSKIP_PORT,CAPSKIP_API_KEY ` --allow-net=127.0.0.1:8080,example.com ` solve.js https://example.com/login
env listesi üç CAPSKIP değişkenini adlandırır. net listesi CapSkip’in adresini ve portunu, bir de siteyi adlandırır. example.com ve sayfa adresini kendi sitenizle değiştirin. Girişlerden herhangi birini çıkarırsanız çalıştırma başarısız olur ve hata neyin eksik olduğunu söyler.
| İzin | Neye izin verir | Bu izin olmadan ne görürsünüz |
|---|---|---|
| env, üç ad | CAPSKIP değişkenlerini okumak | NotCapable: Requires env access to "CAPSKIP_HOST" mesajı ve ardından env bayrağıyla yeniden çalıştırmanızı öneren bir tavsiye. Ayarlanmamış bir değişken de reddedilir, bu yüzden varsayılan değerler işe yaramaz. |
| net, CapSkip’in host ve portu | SDK’nın CapSkip’e yaptığı çağrılar | Mesajı Requires net access to "127.0.0.1:8080" olan bir NetworkException; ardından net bayrağı için aynı tavsiye gelir. |
| net, site | Sayfaya ve forma yaptığınız fetch çağrıları | Siteyi adlandıran bir NotCapable hatası. |
net listesiyle ilgili birkaç kural. Portu olmayan bir host her porta izin verir, bu yüzden example.com hem 80 hem de 443’ü kapsar. Portu olan bir giriş yalnızca o porta izin verir. 127.0.0.1 ve 127.0.0.2 farklı host’lardır. Başka bir host adına yönlendirme için de o host’un listede olması gerekir. example.com adresinden www.example.com adresine yönlendiren bir sayfa, siz onu ekleyene kadar ikinci istekte başarısız olur. Başka hiçbir şey gerekmedi: read, run, sys ya da import izni yok.
Bir terminalde Deno başarısız olmak yerine sorar. Her değişken ve her host için bir kez sorar; hayır demek aynı hataları üretir. Zamanlanmış bir işte terminal olmadığı için hemen başarısız olur. allow-all bayrağı (-A) bu denetimlerin hepsini kaldırır, bu yüzden onu hızlı bir deneme için saklayın.
Daha az yazmak için aynı komutu deno.json içine bir task olarak koyabilirsiniz. Aşağıdaki ilk blok, import map ve bir solve task’ı içeren deno.json dosyasıdır; ikincisi ortamı PowerShell’de ayarlar ve çalıştırır. Deno, task adından sonra verdiğiniz sayfa adresini komuta ekler.
{
"imports": {
"capskip": "npm:[email protected]"
},
"tasks": {
"solve": "deno run --allow-env=CAPSKIP_HOST,CAPSKIP_PORT,CAPSKIP_API_KEY --allow-net=127.0.0.1:8080,example.com solve.js"
}
}$env:CAPSKIP_HOST = "127.0.0.1" $env:CAPSKIP_PORT = "8080" deno task solve https://example.com/login
CAPSKIP_HOST için IP adresini kullanın. localhost gibi bir ad verirseniz bu adın kendisi net listesinde olmalıdır, yoksa SDK getaddrinfo EPERM localhost hatasıyla başarısız olur. Onu listeye eklemek de bir tuzaktır. CapSkip çalışmıyorken localhost, Deno’nun listede olmayan [::1] IPv6 adresini denemesine yol açar. Hata SDK çağrısından değil, bir zamanlayıcıdan fırlatılır; bu yüzden bir NetworkException değildir ve try ile catch onu yakalayamaz.
Engellenen bir çağrıyı, çalışmayan bir CapSkip’ten ayırt edin
İkisi de bir NetworkException olarak gelir, bu yüzden her zaman "is CapSkip running?" diyen bir işleyici sizi yanlış yöne sevk eder. Fark mesajda ve nedendedir. Engellenen bir çağrının mesajı Requires net access ile başlar ve nedeni Deno’nun NotCapable hatasıdır. CAPSKIP_HOST bir ad ise mesaj getaddrinfo EPERM olur ve nedenin kodu bunun yerine EPERM’dir. Çalışmayan bir CapSkip’in mesajı connect ECONNREFUSED ile başlar. Ayrıca Windows’ta Deno altında başarısız olması yaklaşık iki saniye sürer, Node altında ise birkaç milisaniye. Bunu bildirmeden önce duraklıyor gibi görünen bir script takılı kalmamıştır. Aşağıdaki fonksiyon iki tür engeli de denetler. Sondaki tam script onu, tüm akışı saran bir catch bloğunda çağırır.
import { ApiException, NetworkException, TimeoutException } from "capskip";
// Deno's permission errors arrive wrapped in NetworkException. The
// cause is NotCapable for an IP host, and has the code EPERM for a
// host name. Tell them apart from a CapSkip that is not running.
/** @param {any} err */
function explain(err) {
const cause = err?.cause;
if (err instanceof NetworkException) {
const denied = cause instanceof Deno.errors.NotCapable ||
cause?.code === "EPERM";
return denied
? `Deno blocked the call, add a flag: ${err.message}`
: `CapSkip is not reachable: ${err.message || cause?.code}`;
}
if (err instanceof ApiException) return `CapSkip replied: ${err.message}`;
if (err instanceof TimeoutException) return `Too slow: ${err.message}`;
return String(err?.stack ?? err);
}Sessiz bir CapSkip’in script’i takılı bırakmasını engelleyin
SDK, bağlantısına hiçbir zaman aşımı koymaz. CapSkip bir çağrıyı kabul edip sonra hiç yanıt vermezse script sonsuza kadar bekler. Deno hiçbir şey yazdırmaz ve çıkmaz. SDK’nın recaptchaTimeout ayarı yardımcı olmaz. Yalnızca yoklamalar arasında kontrol edilir, bu yüzden gönderme çağrısı ya da bir yoklama cevap beklerken devreye giremez. Node da aynı şekilde davranır. Herhangi bir sarmalayıcı olmadan tek çıkış yolu Ctrl+C’dir.
Çağrıya kendiniz bir üst sınır koyun. Olağan araç AbortSignal.timeout’tur, ama Deno’da burada yanlış seçimdir. Bir abort dinleyicisi olan bir zaman aşımı sinyali, süreci zamanlayıcı tetiklenene kadar ayakta tutar. 1.8 saniye süren bir çözümün etrafına konan 30 saniyelik süre, script’in 30 saniye sonra çıkmasına yol açtı. Çağrı sonuçlandığında temizlediğiniz sade bir setTimeout ise başarıda hemen çıkar.
// The SDK sets no socket timeout, so a CapSkip that accepts the call
// and never answers would hang the script. Race it against a timer,
// and clear the timer so the process can exit on success.
/**
* @param {Promise<any>} promise
* @param {number} ms
*/
function withTimeout(promise, ms) {
const { promise: limit, reject } = Promise.withResolvers();
const timer = setTimeout(
() => reject(new Error(`no answer in ${ms} ms`)),
ms,
);
return Promise.race([promise, limit]).finally(() => clearTimeout(timer));
}Ardından 4. adımdaki bloğu bununla değiştirin. Aynı çözüm çağrısını sarar. explain ve withTimeout’u, onları kullanan satırların üstünde herhangi bir yere yapıştırın. SDK 300 saniye sonra kendiliğinden vazgeçer, bu yüzden 330 saniyelik bir süre yalnızca CapSkip sessizleştiğinde devreye girer.
// The SDK gives up after 300 s by itself, so a 330 s budget only
// fires when CapSkip goes silent. code is typed "string or object"
// (Capy shares the field), so String() hands the form a plain string.
const solving = solver.recaptcha(sitekey, pageUrl);
const { code } = await withTimeout(solving, 330_000);
const token = String(code);Zamanlayıcı kazandığında bekleyen bağlantı hâlâ açıktır; bu yüzden tam örnekteki catch bloğu Deno.exit ile biter. O olmasaydı süreç soket üzerinde beklemeye devam ederdi. Testte, gönderme çağrısına hiç yanıt vermeyen bir CapSkip ile sonuç yoklamalarına hiç yanıt vermeyen bir CapSkip, ikisi de süre dolduktan sonra hatayla sona erdi. Çıkış kodu 1 idi.
Script’te tür denetimi yapın
Deno, JavaScript’i SDK’nın paketle gelen türlerine göre denetleyebilir, ama siz istemedikçe düz bir .js dosyası için hiçbir şey yapmaz. Düz bir .js dosyasında çalıştırılan deno check, kodda bir tür hatası olsa bile hiçbir şey bildirmez. deno.json içinde checkJs’i açmak denetimi gerçek kılar.
{
"imports": {
"capskip": "npm:[email protected]"
},
"compilerOptions": {
"checkJs": true
}
}deno check solve.js
Denetim açıkken host yerine hots gibi yanlış yazılmış bir constructor seçeneği hata verir. Çözüm çağrısının içindeki yanlış yazılmış bir seçenek ise vermez, çünkü seçenekler türü her anahtarı kabul eder; oradaki bir yazım hatası derlenir ve hiçbir şey yapmaz. Denetimi bir yardım olarak görün, bir garanti olarak değil.
Tek bir exe dosyasına derleyin
İzinler komutun parçası olduğu için deno compile onları programın içine sabitleyebilir. Böylece Deno’da reCAPTCHA çözen bir script, Deno kurulu olmayan bir bilgisayarda çalışan tek bir solve.exe olarak dağıtılır. Bu, CapSkip’i ve bir script’i aynı makinede birlikte çalıştıran bir Windows makinesine uygundur.
deno compile ` --allow-env=CAPSKIP_HOST,CAPSKIP_PORT,CAPSKIP_API_KEY ` --allow-net=127.0.0.1:8080,example.com ` --output solve.exe solve.js .\solve.exe https://example.com/login
Bilmeniz gereken dört şey var. İlk derleme dl.deno.land adresinden yaklaşık 33 MB’lık bir çalışma zamanı indirir ve exe yaklaşık 80 MB olur. Ortam değişkenleri yine çalışır, bu yüzden CAPSKIP_PORT dikkate alınır. İzinler derleme sırasında sabitlenir ve exe’nin bunları genişletecek bir bayrağı yoktur: allow-all bayrağını verirseniz o, programın ilk argümanı olur. Ayrıca exe içinde reddedilen bir çağrı, izni derleme sırasında belirtmenizi söyler.
Task Scheduler’ınkine benzeyen bir başlatma, exe’yi çalıştırdı ve testte 0 koduyla çıktı. Çalışma klasörü System32 idi, konsol yoktu ve PATH değişkeninde Deno bulunmuyordu. Gerçek bir zamanlanmış görev kaydedilmedi; bu yüzden orada önemli olan zaman sınırı ve yeniden başlatma ayarları için Windows Task Scheduler işlerinde CAPTCHA çözme rehberine bakın.
CapSkip’i başka bir makinede çalıştırmak
Script ile çözücünün aynı bilgisayarı paylaşması gerekmez. Bağlantı ayarlarından CapSkip’i Server moduna alın; ağ adresinizi veya genel IP’nizi dinler. Ardından iki şeyi değiştirin: CAPSKIP_HOST ve net listesi. Yeni adresi net listesine eklemeyi unutursanız hata onu adlandırır.
$env:CAPSKIP_HOST = "192.168.1.50" $env:CAPSKIP_PORT = "8080" $env:CAPSKIP_API_KEY = "YOUR_API_KEY" deno run ` --allow-env=CAPSKIP_HOST,CAPSKIP_PORT,CAPSKIP_API_KEY ` --allow-net=192.168.1.50:8080,example.com ` solve.js https://example.com/login
Rota internetten geçiyorsa statik bir genel IP kullanın. Yukarıdaki bloğun CAPSKIP_API_KEY için ayarladığı anahtarın aynısıyla API key validation’ı açın. CapSkip, Server modu başladığında portunu her adrese açar. Erişimi yalnızca beklediğiniz makinelerle sınırlamak için diğerleri için bir Windows Firewall engelleme kuralı ekleyin. Çözücü hâlâ sizin kendi Windows makinenizdir ve çözüm başına ücretlendirme hâlâ yoktur.
Tam script
İşte solve.js tek parça hâlinde, zaman aşımı sarmalayıcısı ve hata işleyicisi yerinde. Onu deno.json dosyasının yanına kaydedin ve 6. adımdaki komutla çalıştırın.
import {
ApiException,
CapSkip,
NetworkException,
TimeoutException,
} from "capskip";
// The SDK never reads the environment, so read it here and pass it in.
const host = Deno.env.get("CAPSKIP_HOST") ?? "127.0.0.1";
const port = Number(Deno.env.get("CAPSKIP_PORT") ?? 8080);
const apiKey = Deno.env.get("CAPSKIP_API_KEY") ?? "capskip";
const solver = new CapSkip({ host, port, apiKey });
// The login page to solve, passed on the command line.
const pageUrl = Deno.args[0] ?? "https://example.com/login";
// Deno's fetch keeps no cookies, so collect every Set-Cookie line.
// (headers.get("set-cookie") would glue them into one string.)
const jar = new Map();
/** @param {Response} response */
function keepCookies(response) {
for (const line of response.headers.getSetCookie()) {
const [pair] = line.split(";");
const eq = pair.indexOf("=");
jar.set(pair.slice(0, eq).trim(), pair.slice(eq + 1).trim());
}
}
const cookies = () => Array.from(jar, ([k, v]) => `${k}=${v}`).join("; ");
// Deno's permission errors arrive wrapped in NetworkException. The
// cause is NotCapable for an IP host, and has the code EPERM for a
// host name. Tell them apart from a CapSkip that is not running.
/** @param {any} err */
function explain(err) {
const cause = err?.cause;
if (err instanceof NetworkException) {
const denied = cause instanceof Deno.errors.NotCapable ||
cause?.code === "EPERM";
return denied
? `Deno blocked the call, add a flag: ${err.message}`
: `CapSkip is not reachable: ${err.message || cause?.code}`;
}
if (err instanceof ApiException) return `CapSkip replied: ${err.message}`;
if (err instanceof TimeoutException) return `Too slow: ${err.message}`;
return String(err?.stack ?? err);
}
// The SDK sets no socket timeout, so a CapSkip that accepts the call
// and never answers would hang the script. Race it against a timer,
// and clear the timer so the process can exit on success.
/**
* @param {Promise<any>} promise
* @param {number} ms
*/
function withTimeout(promise, ms) {
const { promise: limit, reject } = Promise.withResolvers();
const timer = setTimeout(
() => reject(new Error(`no answer in ${ms} ms`)),
ms,
);
return Promise.race([promise, limit]).finally(() => clearTimeout(timer));
}
try {
const page = await fetch(pageUrl);
keepCookies(page);
const html = await page.text();
// Adjust these two patterns to your page's markup.
const sitekey = html.match(/data-sitekey="([^"]+)"/)?.[1];
const csrf = html.match(/name="csrfmiddlewaretoken" value="([^"]+)"/)?.[1];
if (!sitekey || !csrf) throw new Error("sitekey or CSRF token not found");
// The SDK gives up after 300 s by itself, so a 330 s budget only
// fires when CapSkip goes silent. code is typed "string or object"
// (Capy shares the field), so String() hands the form a plain string.
const solving = solver.recaptcha(sitekey, pageUrl);
const { code } = await withTimeout(solving, 330_000);
const token = String(code);
// fetch sends no Referer, and a strict site rejects the post without
// one. redirect "manual" keeps the 302 so we can read its new cookie.
const response = await fetch(pageUrl, {
method: "POST",
redirect: "manual",
headers: { Cookie: cookies(), Referer: pageUrl },
body: new URLSearchParams({
csrfmiddlewaretoken: csrf,
username: "YOUR_USERNAME",
password: "YOUR_PASSWORD",
"g-recaptcha-response": token,
}),
});
keepCookies(response);
// A good login answers 302 and rotates the session cookie.
if (response.status !== 302) {
const body = await response.text();
throw new Error(`login rejected: ${response.status} ${body}`);
}
const next = new URL(response.headers.get("location") ?? "/", pageUrl);
const home = await fetch(next, { headers: { Cookie: cookies() } });
// Swap "Welcome back" for a marker your own site shows after login.
const ok = (await home.text()).includes("Welcome back");
console.log(ok ? "logged in" : "NOT logged in");
if (!ok) Deno.exit(2);
} catch (err) {
console.error(explain(err));
Deno.exit(1);
}Deno’da reCAPTCHA çözerken sık görülen hatalar
Bir try bloğu olmadan Deno, ilk sütundaki gibi önce sınıf adını yazdırır. Tam script aynı mesajları kendi önekinin ardından yazdırır.
| Gördüğünüz | Neden | Düzeltme |
|---|---|---|
| Requires env access to "CAPSKIP_HOST" | env izninde bir ad eksik | Üç CAPSKIP adının hepsini listeleyin |
| NetworkException: Requires net access to "127.0.0.1:8080" | CapSkip’in host ve portu net listesinde yok | Onları ekleyin, siteyi de ekleyin |
| NetworkException: connect ECONNREFUSED, yaklaşık 2 saniye sonra | CapSkip çalışmıyor ya da port yanlış | CapSkip’i başlatın ve portu bağlantı ayarlarından kontrol edin |
| NetworkException: getaddrinfo EPERM localhost | Bir host adı kullanılıyor ama net listesinde yalnızca IP var | CAPSKIP_HOST için 127.0.0.1 kullanın |
| ReferenceError: require is not defined | Bir ES modülünde CommonJS çağrısı | Adlandırılmış import’u kullanın |
| TypeError: CapSkip is not a constructor | Varsayılan import, exports nesnesinin tamamını verir | CapSkip’i { CapSkip } biçiminde, adıyla import edin |
| Could not find "capskip" in a node_modules folder | Projenin üstündeki bir package.json, import’ların çözümlenme biçimini geçersiz kılar | Proje klasörüne bir deno.json koyun |
| Çıktı yok, çıkış yok | CapSkip çağrıyı kabul etti ve hiç yanıt vermedi | Çağrıyı withTimeout ile sarın ve Deno.exit çağırın |
| ApiException: ERROR_CAPTCHA_UNSOLVABLE | CapSkip denedi ve başaramadı | Yeni bir görev gönderin, şu konudaki notlara bakın: ERROR_CAPTCHA_UNSOLVABLE |
FAQ
Bayrakları atlayıp allow-all kullanabilir miyim?
Çalışır, ama Deno altında çalıştırmanın amacını ortadan kaldırır. O zaman script’in her şeye ağ, dosya ve ortam erişimi olur; içe aktardığı paketler de buna dahildir. Üç adlık bir liste ile iki host’luk bir liste, korunacak kadar kısadır.
Bu, Deno Deploy’da ya da barındırılan başka bir çalışma ortamında işe yarar mı?
Deno Deploy ve barındırılan diğer çalışma ortamları burada test edilmedi. Başkasının veri merkezindeki bir sunucu, bilgisayarınızdaki 127.0.0.1’e ulaşamaz. Bu yüzden CapSkip’i kontrol ettiğiniz bir Windows makinesinde, statik bir genel IP ile Server modunda çalıştırın ve CAPSKIP_HOST’u ona yöneltin. Platformun o adrese ve porta giden bağlantılara da izin vermesi gerekir, bu yüzden ağ kurallarını kontrol edin. Netlify Functions’ta CAPTCHA çözme rehberi aynı Server modu kurulumunu barındırılan bir function içinden ele alıyor.
Neden CapSkip’i fetch ile çağırmak yerine SDK kullanmalıyım?
CapSkip 2captcha API’siyle uyumludur, bu yüzden in.php ve res.php’ye fetch ile istek atmak da çalışır. O zaman yoklama döngüsünü, geri çekilmeyi (back-off) ve hata eşlemesini kendiniz yazarsınız. SDK ise çeyrek saniyeyle başlayan bir takvimle zaten yoklama yapar, token’ı döndürür ve ApiException, NetworkException ve TimeoutException fırlatır. Bedeli iki ayrıntıdır: izin hataları sarılmış olarak gelir ve SDK hiçbir soket zaman aşımı ayarlamaz.
Diğer CAPTCHA türleri Deno’da aynı şekilde çalışır mı?
Bu rehber için Deno altında yalnızca reCAPTCHA v2 çalıştırıldı. Turnstile ve GeeTest gibi token türleri aynı endpoint’leri çağırır, bu yüzden aynı iki bayrak geçerli olmalıdır, ama bu test edilmedi. Dosya yolu olarak verilen bir görüntü CAPTCHA’sı ayrıca okuma izni gerektirir; URL olarak verilen bir görüntü CAPTCHA’sı ise o sitenin net listesinde olmasını gerektirir. Bir çağrıyı kopyalamadan önce her türün seçenekleri için Node.js CAPTCHA çözücü sayfasına bakın.
Kısa özet
Deno’da reCAPTCHA çözmek için kendi klasörünüze SDK import’unu içeren bir deno.json koyun ve adlandırılmış export’u import edin. CapSkip ayarlarını kendiniz okuyun. env listesiyle ve içinde yalnızca CapSkip’in adresi ile sitenizin bulunduğu bir net listesiyle çalıştırın. Reddedilen bir çağrıyı, çalışmayan bir CapSkip’ten nedenine bakarak ayırt edin. Çözümü sade bir zamanlayıcıyla sınırlayın, çünkü AbortSignal.timeout süreci açık tutar ve sessiz bir CapSkip aksi halde süreci sonsuza kadar takılı bırakır.
- Node.js paketinin desteklediği tüm CAPTCHA türleri: Node.js CAPTCHA çözücü sayfası.
- Düz Node’da onay kutulu reCAPTCHA: Node.js’te reCAPTCHA v2 çözme.
- Onay kutulu çözücünün nasıl çalıştığı: reCAPTCHA v2 çözücü sayfası.
Bir kez derleyip zamanladığınız bir script, ayda binlerce çözüm yapabilir. Bunları kendi Windows makinenizde çalışan bir sınırsız captcha çözücü üzerinden yürütmek, bu sayının asla bir faturaya dönüşmemesi demektir.
