Node.js में GeeTest v3 कैसे हल करें और उसे वापस Post करें

लगभग हर कैप्चा इंटीग्रेशन मानता है कि एक token जाता है और एक निकलता है। GeeTest इस तरह काम नहीं करता। एक हल लौटाता है तीन values जिन्हें एक साथ सबमिट करना ज़रूरी है, और जिस challenge से आपने शुरुआत की थी वह उसे फ़ेच करने के लगभग एक मिनट बाद एक्सपायर हो जाता है। इनमें से कोई भी failure कोई काम का error message नहीं देती, यही वजह है कि GeeTest के झंझटी होने की प्रतिष्ठा है।
दो inputs, उनमें से एक नाशवान
| Value | आजीवन |
|---|---|
gt | प्रति साइट स्थिर। इसे स्वतंत्र रूप से कैश करें |
challenge | एक बार इस्तेमाल, लगभग 60 सेकंड में ख़त्म |
दोनों साइट के अपने GeeTest init एंडपॉइंट से आते हैं। चैलेंज को दोबारा उपयोग योग्य मानना ही वह वजह है कि इंटीग्रेशन टेस्टिंग में पास होते हैं और प्रोडक्शन में ढह जाते हैं, जहाँ कतार में देरी हल को एक्सपायरी के पार धकेल देती है।
Setup
npm install capskip
const { CapSkip } = require('capskip');
const solver = new CapSkip({
host: '127.0.0.1',
port: 8080,
recaptchaTimeout: 300, // GeeTest uses this, not defaultTimeout
});वह अंतर मायने रखता है। defaultTimeout केवल image कैप्चा को नियंत्रित करता है; सब कुछ interactive इस्तेमाल करता है recaptchaTimeout.
Solving
const result = await solver.geetest( '81388ea1fc187e0c335c0a8907ff2625', // gt, static per site '7cf6a8b1a2c34d5e6f7089abcdef0123', // challenge, fetched seconds ago 'https://example.com/login', ); console.log(result.challenge, result.validate, result.seccode);
वे तीन प्रॉपर्टीज़ ही जवाब हैं। result.code भी भरा जाता है, लेकिन GeeTest के लिए यह किसी सबमिट करने योग्य चीज़ के बजाय raw JSON string रखता है, इसलिए आदतन इसकी ओर हाथ बढ़ाना एक भ्रमित करने वाली विफलता पैदा करता है।
इसका उपयोग करें the challenge जो वापस आता है, वह नहीं जो आपने पास किया था। ये हमेशा एक जैसे नहीं होते।
पूरा flow
const { CapSkip } = require('capskip');
const solver = new CapSkip();
const LOGIN = 'https://example.com/login';
// 1. Fresh pair, cache-busted. Cached init responses return spent challenges.
const init = await (await fetch(
`https://example.com/geetest/init?t=${Date.now()}`,
)).json();
// 2. Solve immediately. Nothing slow between here and the previous step.
const result = await solver.geetest(init.gt, init.challenge, LOGIN);
// 3. Post all three together with the real form fields.
const response = await fetch(LOGIN, {
method: 'POST',
body: new URLSearchParams({
geetest_challenge: result.challenge,
geetest_validate: result.validate,
geetest_seccode: result.seccode,
username: '...',
password: '...',
}),
});cache-busting timestamp असली काम कर रहा है। GeeTest init endpoints अक्सर किसी CDN या प्रॉक्सी द्वारा कैश किए जाते हैं, और एक कैश की गई response आपको एक ऐसा challenge सौंपती है जिसे कोई पहले ही उपयोग कर चुका है।
वे field नाम सामान्य GeeTest v3 परंपरा हैं, हालांकि कोई site उनका नाम बदल सकती है। मान लेने से पहले असली form जांचें।
batching का जाल
यहीं Node की ergonomics आपके खिलाफ़ काम करती हैं। स्पष्ट parallel संस्करण गलत है:
// WRONG: every challenge is fetched up front, so the later solves // start against pairs that have already expired. const pairs = await Promise.all(urls.map(fetchPair)); const results = await Promise.all( pairs.map((p, i) => solver.geetest(p.gt, p.challenge, urls[i])));
fetch और solve को एक ही task के अंदर रखें ताकि प्रत्येक जोड़ी जारी किए जाने के सेकंडों के भीतर उपयोग हो:
// RIGHT: each task fetches its own pair immediately before solving.
const results = await Promise.all(urls.map(async (url) => {
const pair = await fetchPair(url);
return solver.geetest(pair.gt, pair.challenge, url);
}));AsyncCapSkip इसके एक alias के रूप में एक्सपोर्ट किया जाता है CapSkip यहां, इसलिए इस्तेमाल करने के लिए कोई अलग async client नहीं है। Promise.all यही पूरी कहानी है।
Errors
const {
ValidationException, NetworkException, ApiException, TimeoutException,
} = require('capskip');
try {
const result = await solver.geetest(gt, challenge, pageUrl);
} catch (err) {
if (err instanceof ValidationException) { /* missing gt or challenge */ }
else if (err instanceof NetworkException) { /* CapSkip not running */ }
else if (err instanceof ApiException) { /* usually an expired challenge */ }
else if (err instanceof TimeoutException) { /* exceeded recaptchaTimeout */ }
else throw err;
}ज़्यादातर GeeTest विफलताएँ इस रूप में आती हैं ApiException और इसका मतलब है challenge एक्सपायर हो गया। उसी जोड़ी के साथ फिर से आज़माना कभी काम नहीं करता। एक नई fetch करें।
अक्सर पूछे जाने वाले सवाल
मैं सिर्फ़ result.code का उपयोग क्यों नहीं कर सकता?
क्योंकि GeeTest’s उत्तर तीन values होता है। code पूर्णता के लिए raw JSON रखता है जबकि SDK काम के हिस्सों को इसमें विस्तृत कर देता है challenge, validate और seccode. उन्हें सबमिट करें।
क्या मैं gt मान को cache कर सकता हूँ?
हाँ। यह gt एक site पहचानकर्ता है और शायद ही कभी बदलता है। challenge नाशवान आधा हिस्सा है और हर बार नया प्राप्त करना ज़रूरी है।
क्या यह GeeTest v4 संभालता है?
The geetest method v3 को लक्षित करता है, वह slide puzzle जो एक पर बना है gt और challenge जोड़ी। v4 ने पैरामीटर model बदल दिया, इसलिए मौजूदा जांचें API डॉक्युमेंटेशन यह मान लेने से पहले कि वही कॉल काम करती है।
सारांश
एक cache-busted pair fetch करें, तुरंत हल करें, फिर post करें challenge, validate और seccode एक साथ। लौटाए गए challenge का उपयोग करें, केवल कैश करें gt, और समानांतर में चलाते समय fetch और solve को एक ही task के अंदर रखें।
अन्य भाषाएँ इस पर हैं GeeTest solver पेज, इस पर व्यापक Node सरफ़ेस Node.js कैप्चा सॉल्वर पेज, और हमारे यहाँ एक लाइव पहेली है GeeTest v3 demo। CapSkip करता है कैप्चा बायपास लोकल रूप से, इसलिए हल की मात्रा की कोई लागत नहीं।
