Cara Memecahkan reCAPTCHA v2 di Node.js, Termasuk Invisible

reCAPTCHA v2 memiliki tiga varian dan semuanya bermuara pada metode Node.js yang sama. Checkbox adalah panggilan polosnya, Invisible dan Enterprise adalah opsi pada argumen ketiga, dan keduanya dapat digabungkan. Paketnya juga menyertakan definisi TypeScript-nya sendiri, sehingga untuk ini tidak diperlukan @types instal.
Penyiapan
npm install capskip
CapSkip memecahkan di komputer Anda sendiri, jadi aplikasi desktop harus berjalan lebih dulu. Lalu arahkan client ke port yang tercantum di pengaturannya:
const { CapSkip } = require('capskip');
const solver = new CapSkip({
apiKey: 'capskip', // any string when key validation is off
host: '127.0.0.1',
port: 8080,
recaptchaTimeout: 300, // seconds
});Di produksi, baca detail koneksi dari environment:
const solver = new CapSkip({
apiKey: process.env.CAPSKIP_API_KEY || 'capskip',
host: process.env.CAPSKIP_HOST || '127.0.0.1',
port: parseInt(process.env.CAPSKIP_PORT || '8080', 10),
});Tiga varian
| Varian | Opsi untuk menambahkan |
|---|---|
| Checkbox | tidak ada |
| Invisible | { invisible: 1 } |
| Enterprise | { enterprise: 1 } |
| Invisible Enterprise | kedua kunci |
// Checkbox: sitekey and page URL, nothing else.
const result = await solver.recaptcha(
'6Lc...YOUR_SITEKEY',
'https://example.com/login',
);
console.log(result.code); // g-recaptcha-response token
// Invisible.
await solver.recaptcha(sitekey, pageUrl, { invisible: 1 });
// Enterprise, and both at once.
await solver.recaptcha(sitekey, pageUrl, { enterprise: 1 });
await solver.recaptcha(sitekey, pageUrl, { enterprise: 1, invisible: 1 });Perhatikan gaya argumennya. Node menerima sitekey dan URL secara posisional, tidak seperti SDK Python yang memakai keyword. Memindahkan kode di antara keduanya adalah tempat sebagian besar kesalahan muncul.
TypeScript
Definisi tipe disertakan dalam paketnya, jadi ini berfungsi tanpa instalasi tambahan:
import { CapSkip, SolveResult } from 'capskip';
const solver = new CapSkip({ host: '127.0.0.1', port: 8080 });
const result: SolveResult = await solver.recaptcha(sitekey, pageUrl);SolveResult membawa captchaId dan code untuk setiap jenis, userAgent untuk Turnstile, dan tiga kolom GeeTest. Untuk reCAPTCHA hanya code penting.
Mendapatkan sitekey yang benar
Ini adalah data-sitekey atribut pada kontainer widget, atau argumen pertama untuk grecaptcha.render ketika mode Invisible berarti tidak ada kontainer yang terlihat. Nilainya selalu diawali dengan 6L dan bersifat publik.
URL harus berupa halaman tempat widget dirender. Mengirimkan handler formulir atau redirect pasca-login adalah penyebab umum token yang terpecahkan mulus lalu gagal verifikasi.
Mengirimkan token
const body = new URLSearchParams({
'g-recaptcha-response': result.code,
username: '...',
password: '...',
});
const response = await fetch('https://example.com/login', {
method: 'POST',
body,
});Token bersifat sekali pakai dan bertahan sekitar dua menit, jadi pecahkan selambat mungkin. Jika situs meneruskan token ke callback JavaScript alih-alih ke kolom formulir, pemecahannya sama tetapi cara pengirimannya berbeda, dan hal itu dibahas dalam pemecah callback reCAPTCHA v2 dibahas halaman ini.
Memecahkan beberapa sekaligus
const [a, b] = await Promise.all([ solver.recaptcha(sitekeyA, 'https://a.example.com'), solver.recaptcha(sitekeyB, 'https://b.example.com'), ]); console.log(a.code, b.code);
Paket ini juga mengekspor AsyncCapSkip, tetapi di Node itu hanya alias dari CapSkip. I/O Node sudah asinkron dan setiap metode sudah mengembalikan Promise, jadi ini ada semata-mata agar kode yang dipindahkan dari SDK Python tetap berfungsi. Beralih ke sana tidak memberi keuntungan apa pun.
Kesalahan
const {
ValidationException, NetworkException, ApiException, TimeoutException,
} = require('capskip');
try {
const result = await solver.recaptcha(sitekey, pageUrl);
} catch (err) {
if (err instanceof ValidationException) { /* bad arguments */ }
else if (err instanceof NetworkException) { /* CapSkip not running */ }
else if (err instanceof ApiException) { /* bad sitekey or url */ }
else if (err instanceof TimeoutException) { /* polling timed out */ }
else throw err;
}Keempatnya memperluas basis yang sama, sehingga menangkap CapSkipError menangani semuanya dalam satu cabang jika Anda lebih suka begitu.
Pertanyaan yang sering diajukan
Apakah saya perlu melakukan polling untuk mendapatkan hasilnya?
Tidak. Client melakukan polling secara internal dan Promise-nya selesai dengan token yang sudah jadi. Pengecekan dimulai setelah 250ms lalu melambat menuju pollingInterval, yang biasanya lebih baik daripada loop buatan tangan.
Apakah ini bekerja dengan ESM dan sintaks import?
Ya. Contoh di sini menggunakan require demi keringkasan, tetapi import { CapSkip } from 'capskip' berfungsi, dan definisi TypeScript bawaannya ikut serta.
Bisakah saya menggunakan ini bersama Puppeteer atau Playwright?
Ya. Pecahkan tokennya dengan SDK ini, lalu suntikkan ke halaman menggunakan page.evaluate sebelum mengirim. pemecah CAPTCHA Node.js membahas sisi otomatisasi browser.
Ringkasan
Satu metode, tiga varian, dipilih dengan invisible dan enterprise. Argumen bersifat posisional, token berakhir di result.code, dan Promise.all adalah semua yang Anda butuhkan untuk konkurensi karena AsyncCapSkip hanyalah alias di sini.
Cakupan Node yang lebih luas ada di pemecah CAPTCHA Node.js halaman, bahasa lain di pemecah reCAPTCHA v2 halaman, dan ada demo v2 langsung untuk diuji. CapSkip adalah pemecah captcha lokal, sehingga tidak ada tagihan per pemecahan.
