Postman में कैप्चा कैसे हल करें और token के लिए poll कैसे करें

solve captcha in postman - How to Solve CAPTCHA in Postman and Poll for the Token

आप Postman में कैप्चा हल कर सकते हैं, बिना application code की एक भी line लिखे। API 2captcha compatible है और आपकी अपनी मशीन पर ही रहता है, इसलिए बस दो requests लगती हैं: पहले /in.php पर task POST करें और ID संभालकर रखें, फिर /res.php को तब तक poll करें जब तक जवाब न आ जाए। एक छोटा post-response script उस दूसरी request को एक loop में बदल देता है, और एक collection variable ID को दोनों के बीच पहुँचाता है। इस गाइड में सटीक fields, दोनों scripts, और वह एक setting है जो loop को हमेशा चलते रहने से रोकती है।

आपको क्या चाहिए

  • Postman desktop app। यह बिना किसी agent के सीधे 127.0.0.1 से बात करता है। web app नीचे कवर किया गया है और उसे एक अतिरिक्त चीज़ चाहिए
  • CapSkip चालू और पहुँच में हो। Local mode उसी मशीन पर मौजूद client के लिए 127.0.0.1 के port 8080 पर सुनता है, और Server mode आपके network या public IP पर सुनता है ताकि कोई laptop, कोई साथी या कोई hosted runner उस तक पहुँच सके। दोनों यहाँ मिलेंगे: कनेक्शन सेटिंग्स
  • एक sitekey और एक page URL, जिस पर हल करना है

और कुछ नहीं। न SDK, न कोई dependency, न कोई खाता। Key validation डिफ़ॉल्ट रूप से बंद है, इसलिए key की जगह कोई भी ग़ैर-ख़ाली string चल जाती है, और कुछ भी न भेजने पर solve के बजाय ERROR_WRONG_USER_KEY मिलता है।

पहले तीन collection variables सेट करें

इन्हें किसी environment के बजाय collection पर रखें। collection variable export के साथ चलता है, इसलिए कोई और इसे import करे तब भी पूरी चीज़ काम करती रहती है।

वेरिएबलशुरुआती valueक्यों
baseUrlhttp://127.0.0.1:8080सॉल्वर के किसी server पर जाने पर बदलने की एक ही जगह
apiKeycapskipकोई भी ग़ैर-ख़ाली string। Validation डिफ़ॉल्ट रूप से बंद है
captchaIdख़ालीsubmit script इसे लिखती है, poll request इसे पढ़ती है

Request 1: task submit करें

{{baseUrl}}/in.php पर एक POST, form body के साथ। x-www-form-urlencoded चुनें, raw JSON नहीं: API form fields पढ़ता है।

कुंजीValue
key{{apiKey}}
methoduserrecaptcha
googlekeyYOUR_SITEKEY
pageurlhttps://example.com/page-with-recaptcha
json1

json=1 field Postman में terminal के मुक़ाबले ज़्यादा मायने रखता है। इसके बिना reply सिर्फ़ plain string OK होती है, उसके बाद एक pipe और ID, जिन्हें फिर आपको हाथ से अलग करना पड़ता है। इसके साथ आपको एक object मिलता है और pretty printer काम करता है।

इसे Scripts tab में, Post-response के नीचे जोड़ें। पुराने Postman versions इसी tab को Tests कहते हैं।

// Post-response script on the submit request.
const body = pm.response.json();

pm.test('task accepted', function () {
    pm.expect(body.status).to.eql(1);
});

// Hand the ID to the polling request.
pm.collectionVariables.set('captchaId', body.request);

response की शक्ल हर कैप्चा प्रकार के लिए एक जैसी होती है। task स्वीकार हो जाने पर status 1 होता है, और काम की value हमेशा request field में होती है।

{"status": 1, "request": "2122988149"}

parameter का नाम देखते रहें। reCAPTCHA googlekey लेता है और Turnstile sitekey लेता है, और ग़लत वाला भेजना ही ERROR_GOOGLEKEY reply की आम वजह है। Turnstile सॉल्वर पेज पर challenge pages के लिए पूरी field list है, जिनके लिए page से scrape किए गए cData और chlPageData values भी चाहिए होते हैं।

वही request, बाक़ी आठ प्रकारों के लिए

सिर्फ़ submit request बदलती है। पाँच method values उन सभी प्रकारों को कवर कर लेती हैं जिन्हें CapSkip सपोर्ट करता है, और variants अलग endpoints नहीं बल्कि उसी form body पर अतिरिक्त fields हैं। Request 1 की कॉपी बनाएँ, आख़िरी कॉलम लागू करें, और request का बाक़ी हिस्सा वैसा ही रहने दें।

Typemethod को इस पर सेट करेंफिर body में यह बदलें
इमेज, अपलोड की गई फ़ाइलmethod = postbody को form-data पर स्विच करें और इमेज को file के रूप में अटैच करें
इमेज, base64method = base64googlekey और pageurl हटा दें, एन्कोडेड इमेज को body में भेजें
reCAPTCHA v2 checkboxmethod = userrecaptchaकुछ नहीं। ऊपर दिखाई गई request यही है
reCAPTCHA v2 Invisiblemethod = userrecaptchainvisible को 1 value के साथ जोड़ें
reCAPTCHA Enterprisemethod = userrecaptchaenterprise को 1 value के साथ जोड़ें
reCAPTCHA v3method = userrecaptchaversion को v3 पर सेट करके जोड़ें, और एक action भी
Turnstile विजेटmethod = turnstilegooglekey का नाम बदलकर sitekey करें
Turnstile चैलेंज पेजmethod = turnstilegooglekey का नाम बदलकर sitekey करें, फिर data और pagedata जोड़ें
GeeTest v3method = geetestgooglekey की जगह gt और challenge भेजें

इनमें से दो पर Postman में ख़ास ध्यान देना होता है। अपलोड की गई इमेज अकेली ऐसी है जो x-www-form-urlencoded इस्तेमाल नहीं कर सकती, क्योंकि फ़ाइल के लिए multipart body चाहिए, इसलिए उसी एक request को form-data पर स्विच करें। और GeeTest समय-सीमा पर चलता है: उसका challenge value क़रीब एक मिनट में expire हो जाता है, इसलिए पहले सहेजा हुआ value दोबारा इस्तेमाल करने के बजाय भेजने से ठीक पहले लाएँ।

polling request कभी नहीं बदलती। इसे collection के रूप में बनाने की असली वजह यही है: एक ही Request 2 सूची के हर प्रकार के लिए काम करती है, क्योंकि जवाब हमेशा एक ही आकार में आता है।

Request 2: जवाब आने तक poll करें

{{baseUrl}}/res.php पर एक POST, उसी form body style के साथ।

कुंजीValue
key{{apiKey}}
actionget
id{{captchaId}}
json1

job के चलते रहने के दौरान यह CAPCHA_NOT_READY लौटाता है, बिल्कुल इसी वर्तनी में, ग़ायब अक्षर समेत। यह एक status है, error नहीं, और इसका एकमात्र सही जवाब है दोबारा पूछना।

// Post-response script on the polling request.
const body = pm.response.json();
const tries = Number(pm.collectionVariables.get('tries') || 0);

if (body.request === 'CAPCHA_NOT_READY' && tries < 20) {
    // Run this same request again.
    pm.collectionVariables.set('tries', tries + 1);
    pm.execution.setNextRequest(pm.info.requestId);
} else {
    pm.collectionVariables.set('captchaToken', body.request);
    pm.collectionVariables.set('tries', 0);
    pm.execution.setNextRequest(null);
}

उस script में तीन बातें ख़ास तौर पर कहने लायक़ हैं, क्योंकि हर एक आपकी पूरी दोपहर ले जा सकती है।

loop सिर्फ़ Collection Runner में चलता है। Postman का अपना documentation साफ़ कहता है कि जब आप कोई अकेली request भेजते हैं तो setNextRequest का कोई असर नहीं होता, इसलिए polling request पर Send क्लिक करने से वह बस एक बार चली जाती है और script मरी हुई लगती है। पूरी collection चलाएँ, Postman CLI चलाएँ या Newman।

counter वैकल्पिक नहीं है। बिना किसी सीमा के, जो task कभी हल नहीं होता वह तब तक loop करता रहता है जब तक आप run को हाथ से न रोकें। पाँच सेकंड के अंतर पर बीस कोशिशें यानी सौ सेकंड से ज़्यादा का इंतज़ार, जो reCAPTCHA v2 job को लगने वाले 15 से 20 सेकंड को आराम से कवर कर लेता है।

request को ID से reference करें। pm.info.requestId पास करने से loop उसी request की ओर इशारा करता है जो अभी चल रही है, इसलिए बाद में उसका नाम बदलने से chain चुपचाप टूटती नहीं।

runner को एक delay दें, वरना आप endpoint को पीट डालेंगे

ऊपर वाली script उतनी ही तेज़ी से loop करती है जितनी तेज़ी से runner चल सके, और दो सेकंड से चल रहे किसी job को poll करना बेकार मेहनत है। Collection Runner की run configuration में एक Delay field होता है, मिलीसेकंड में, जो हर request से पहले लगता है। उसे 5000 कर दें।

पहली poll से पहले कितना इंतज़ार करना है, यह इस पर निर्भर करता है कि आपने submit क्या किया:

Typeइससे पहले तैयार नहीं
इमेज1 सेकंड
reCAPTCHA v215 से 20 सेकंड
reCAPTCHA v310 से 15 सेकंड
GeeTest v3लगभग 5 सेकंड

Newman में यही setting एक command line flag है, इसलिए जो collection app में काम करती है वह CI में बिना बदलाव के काम करती है।

# npm install -g newman
newman run captcha.postman_collection.json --delay-request 5000

इसके बजाय plain text reply पढ़ना

json=1 हटा दें और body text के रूप में वापस आती है, जो कभी-कभी वही होता है जो आप चाहते हैं। दो helpers इसे संभाल लेते हैं।

// Plain text mode: OK|2122988149
const id = pm.response.text().split('|')[1];

// Turnstile also returns the user agent, as a header.
const ua = pm.response.headers.get('X-Turnstile-User-Agent');

वह header कोई अजूबा नहीं है। Cloudflare किसी Turnstile token को उस browser fingerprint से बाँध देता है जिसने उसे बनाया था, इसलिए token उसी user agent के साथ submit होना चाहिए, वरना site उसे ठुकरा देती है जबकि token खुद बिल्कुल वैध होता है।

एक और नियम जो ख़ास तौर पर Postman इस्तेमाल करने वालों को पकड़ता है, क्योंकि इस app में Send दो बार क्लिक कर देना बहुत आसान है: कोई नतीजा सिर्फ़ एक ही बार पढ़ा जा सकता है। उसी ID को दूसरी बार पढ़ने पर ख़ाली response आता है, जो हूबहू किसी नाकाम solve जैसा दिखता है। पहली बार पढ़ते ही token को किसी variable में रख लें।

agent वाला सवाल, और Postman को किसी server पर लगाना

अगर आप desktop app के बजाय Postman web app इस्तेमाल करते हैं, तो requests किसी agent से होकर जाती हैं, और agent का चुनाव तय करता है कि 127.0.0.1 पहुँच में है भी या नहीं। Cloud Agent, Postman के अपने infrastructure में चलता है और किसी private network पर मौजूद किसी भी चीज़ तक नहीं पहुँच सकता। Desktop Agent आपकी मशीन पर चलता है और पहुँच सकता है।

आप Postman कैसे चलाते हैंक्या यह किसी लोकल सॉल्वर तक पहुँच सकता है?
डेस्कटॉप appहाँ, किसी agent की ज़रूरत नहीं
Desktop Agent के साथ web appहाँ, agent आपकी मशीन से होकर route करता है
Cloud Agent के साथ web appनहीं, यह किसी private network को देख नहीं सकता

Server mode इस गणित को बदल देता है। CapSkip को ऐसी मशीन पर चलाएँ जो आपके network या किसी public IP पर सुनती हो, baseUrl variable को उस पर लगाएँ, और collection की हर request उसी के पीछे चली जाती है। और कुछ नहीं बदलता, क्योंकि बदला सिर्फ़ पता है।

# The collection variable is the only edit.
baseUrl = http://YOUR_SERVER_IP:8080

स्टैटिक public IP की सलाह दी जाती है, और उसके steps यहाँ हैं: कनेक्शन सेटिंग्स। Server mode अब भी आपका अपना hardware है और अब भी unmetered है: यह बदलता है कि सॉल्वर कहाँ सुनता है, न कि यह कि उसका मालिक कौन है।

आम errors और उनका मतलब

आप जो देखते हैंकारणफिक्स
ERROR_WRONG_USER_KEYkey field ख़ाली आया क्योंकि {{apiKey}} resolve नहीं हुआapiKey को collection पर परिभाषित करें, किसी ऐसे environment में नहीं जिसे चुनना आपको याद रखना पड़े
ERROR_WRONG_METHODmethod में, या action की value में कोई टाइपोये दोनों form fields हैं, HTTP verbs नहीं: submit एक method field लेता है, polling के लिए action field को get पर सेट करना होता है
ERROR_GOOGLEKEYuserrecaptcha को कोई Turnstile sitekey भेजा गयाmethod को field के नाम से मिलाएँ
ERROR_PAGEURLpage URL में scheme नहीं है, या वह कटा हुआ हैhttps शामिल करें, और query string के बजाय form body इस्तेमाल करें
ख़ाली response bodyवह ID एक बार पहले ही पढ़ी जा चुकी हैपहली बार पढ़ते ही token रख लें; नए के लिए दोबारा submit करें
request नहीं भेजी जा सकी, connection refusedउस पते पर कोई नहीं सुन रहासॉल्वर शुरू करें, या जाँचें कि Desktop Agent चुना हुआ है
script चलती है लेकिन कुछ loop नहीं होताआपने collection चलाने के बजाय Send क्लिक कियाsetNextRequest सिर्फ़ किसी collection run में ही काम करता है

API जो भी कोड लौटा सकता है, उसकी सटीक शब्दावली यहाँ है: API डॉक्युमेंटेशन.

अक्सर पूछे जाने वाले सवाल

क्या मैं पूरा काम एक ही request में कर सकता हूँ?

तकनीकी तौर पर हाँ, किसी pre-request script में pm.sendRequest के साथ, और यह शायद ही कभी सार्थक होता है। sandbox छोटे scripts के लिए बना है, इसलिए blocking poll के दौरान request बिना किसी feedback के अटकी हुई लगती है। दो requests और runner आपको हर कोशिश दिखाते हैं, और code के बजाय Postman में रहने की वजह भी यही है।

क्या यह Newman के ज़रिए CI में चलेगा?

हाँ। setNextRequest Newman और Postman CLI में ठीक वैसे ही काम करता है जैसे app में, इसलिए export की गई collection बिना बदलाव के चलती है। एक ही चीज़ सुलझानी होती है, पहुँच: किसी hosted runner का अपना loopback address होता है, इसलिए सॉल्वर को Server mode में ऐसे पते पर होना चाहिए जहाँ तक runner route कर सके।

क्या इस पर कोई rate limit है कि मैं कितने queue कर सकता हूँ?

नहीं। जितने चाहें उतने tasks submit करें और हर ID को अलग से poll करें। काम किसी और की साझा queue के बजाय आपके अपने hardware पर होता है, इसलिए सीमा यह है कि आपकी मशीन उन्हें कितनी तेज़ी से निपटाती है, न कि कोई quota या balance।

Postman से आगे कब बढ़ें

Postman सही औज़ार है यह साबित करने के लिए कि API काम करता है, किसी नए कैप्चा प्रकार को टटोलने के लिए, और किसी साथी को कुछ ऐसा देने के लिए जिसे वह import करके चला सके। production के लिए यह ग़लत औज़ार है, ज़्यादातर polling की वजह से: runner हर बार अपनी तय देरी पूरी होने तक इंतज़ार करता है, जबकि आधिकारिक SDKs 250 मिलीसेकंड पर polling शुरू करते हैं और फिर धीमे होते जाते हैं, इसलिए तेज़ solve तेज़ी से लौटता है। वे error strings को typed exceptions में भी बदल देते हैं।

किसी shell script में यही दो calls के लिए देखें: cURL वॉकथ्रू। दोनों ही सूरतों में calls आपकी अपनी मशीन पर जाती हैं, और इसीलिए किसी collection को असीमित कैप्चा सॉल्वर की ओर लगाना सार्थक है: आप fields ठीक करते हुए collection बीस बार चला सकते हैं, और इसमें आपके अपने CPU के अलावा कुछ खर्च नहीं होता।