Python में Capy Puzzle कैसे हल करें: key से फॉर्म पोस्ट तक

Python में Capy Puzzle हल करने के लिए, पेज से साइट की PUZZLE_ key पढ़ें, capskip पैकेज से solver.capy() को उस key और पेज URL के साथ कॉल करें, फिर वह जो तीन वैल्यू लौटाता है, उन्हें capy_captchakey, capy_challengekey और capy_answer फॉर्म फ़ील्ड में एक साथ और तुरंत पोस्ट करें। पेज लाना और फॉर्म भेजना, दोनों एक ही requests session से करें, ताकि साइट की cookies जवाब के साथ वापस जाएँ। लोगों को जो बात चौंकाती है, वह है नतीजे का रूप। ज़्यादातर कैप्चा टाइप एक token लौटाते हैं; Capy तीन वैल्यू लौटाता है जो सिर्फ़ एक सेट के रूप में काम करती हैं, और उनमें से एक जल्दी expire हो जाती है। CapSkip ने Capy Puzzle को वर्ज़न 1.4.0 में जोड़ा। यह गाइड key, कॉल, जानबूझकर रखा गया दो सेकंड का ठहराव, सबमिट, दोबारा कोशिशें और एक साथ कई solve चलाना कवर करती है।
आपको क्या चाहिए
- किसी Windows मशीन पर चल रहा CapSkip 1.4.0 या उसके बाद का संस्करण। Capy सपोर्ट उसी रिलीज़ में आया था, CaptchaFox और Friendly Captcha के साथ।
- Python 3.10 या उसके बाद का संस्करण, और capskip पैकेज का 1.3.0 या उसके बाद का वर्ज़न, जो capy() method वाली पहली रिलीज़ है। सैंपल requests भी इस्तेमाल करते हैं, और parallel solve वाला सेक्शन httpx इस्तेमाल करता है।
- टारगेट पेज से दो वैल्यू: Capy key, जो PUZZLE_ से शुरू होती है, और उस पेज का URL जिस पर widget चलता है। स्टेप 1 दिखाता है कि key कहाँ मिलती है, और वहीं से यह भी पता चलता है कि आपको तीसरी, वैकल्पिक वैल्यू की ज़रूरत है या नहीं।
- सॉल्वर के लिए एक पता। Local मोड में CapSkip केवल उसी डिवाइस के लिए 127.0.0.1 पर जवाब देता है; Server मोड में वह आपके नेटवर्क पते या पब्लिक IP पर सुनता है, ताकि किसी दूसरी मशीन पर चल रही script API के ज़रिए उसे कॉल कर सके। दोनों यहाँ सेट किए जाते हैं: कनेक्शन सेटिंग्स, और कब स्विच करना है, यह नीचे के एक सेक्शन में बताया गया है।
# Quoted, so cmd.exe does not read >= as a redirect pip install "capskip>=1.3.0" requests httpx
स्टेप 1: PUZZLE_ key और Capy host खोजें
आपको जो कुछ चाहिए, वह सब टारगेट पेज से ही मिलता है, और key सार्वजनिक होती है और हर विज़िटर के लिए एक जैसी होती है। साइटें इसे दो जगह रखती हैं। widget script के URL का k पैरामीटर उस HTML में होता है जिसे requests डाउनलोड करता है। ब्राउज़र में widget चल जाने के बाद key एक hidden capy_captchakey input में भी होती है, जिसे widget फॉर्म में लिखता है, और DevTools में यह वहीं दिखती है। PUZZLE_ prefix के लिए एक regular expression इसे दोनों में से किसी भी जगह ढूँढ लेता है।
import re import requests PAGE_URL = "https://example.com/login" session = requests.Session() html = session.get(PAGE_URL, timeout=30).text # The widget script's k= parameter. The capy_captchakey input only # exists once the widget has run in a browser. key = re.search(r"PUZZLE_[A-Za-z0-9_-]+", html) # The widget script's own host; None means the default one. host = re.search(r"(https://[^\"'\s<>]+?)/puzzle/get_js/", html) api_server = host.group(1) if host else None print(key and key.group(0), api_server)
जब आप script टैग देख रहे हों, तो उसका host भी नोट कर लें। script URL में /puzzle/get_js/ से पहले का पूरा हिस्सा वह Capy API है जिसके पीछे key रहती है, और CapSkip उसे api_server कहता है। इसका डिफ़ॉल्ट https://jp.api.capy.me है, जहाँ लाइव सर्विस चलती है, इसलिए इसकी ज़रूरत सिर्फ़ तब है जब कोई पेज widget को कहीं और से लोड करे। एक जाल दूसरे सॉल्वरों के दस्तावेज़ों से आता है: उनमें से कई अब भी क्षेत्रीय prefix के बिना api.capy.me दिखाते हैं, और वह host अब resolve नहीं होता। अगर कोई पुराना सैंपल इसे सेट करता है, तो यह ऑप्शन हटा दें।
पेज जानबूझकर एक requests.Session के ज़रिए लाया जाता है। स्टेप 3 में आप जो फॉर्म सबमिट करते हैं, वह अक्सर पेज की सेट की हुई session cookie पर निर्भर होता है, और session object उसे बिना किसी अतिरिक्त कोड के वापस भेज देता है।
स्टेप 2: capy() कॉल
Python में Capy Puzzle हल करने के लिए आपको एक ही method चाहिए। यह key और पेज URL लेता है, साथ में वैकल्पिक keyword arguments भी, और डिफ़ॉल्ट host वाले पेज के लिए उसे बस इन्हीं दो वैल्यू की ज़रूरत होती है।
# pip install "capskip>=1.3.0"
from capskip import CapSkip
solver = CapSkip(host="127.0.0.1", port=8080)
result = solver.capy("PUZZLE_YOUR_KEY", "https://example.com/login")
print(result["captchakey"]) # goes in capy_captchakey
print(result["challengekey"]) # goes in capy_challengekey
print(result["answer"]) # goes in capy_answerनतीजा एक सादा dict है। नाम वाली तीनों keys पढ़ें। code key में सर्वर का पूरा जवाब object होता है, चारों फ़ील्ड वाला एक dict, जो logging के लिए काम आता है, और respKey एक खाली स्ट्रिंग है जो सिर्फ़ दूसरी सर्विसों के साथ compatibility के लिए मौजूद है। answer एक लंबी स्ट्रिंग है जो कुछ-कुछ 0xax8ex0xax84x जैसी शुरू होती है: यह वह ड्रैग पाथ है जिसे widget टुकड़ा खिसकते समय रिकॉर्ड करता, कोई coordinate नहीं।
method जिन ऑप्शन को स्वीकार करता है
रिक्वेस्ट जाने से पहले capy() method हर वह keyword argument हटा देता है जिसकी वैल्यू None हो, इसलिए आप स्टेप 1 वाला host हर कॉल पर पास कर सकते हैं और यह फ़ैसला regex पर छोड़ सकते हैं कि वह भेजा जाए या नहीं।
result = solver.capy(
key.group(0),
PAGE_URL,
# None (no get_js script on the page) is dropped, and CapSkip
# then uses its default host.
api_server=api_server,
# Poll every half second; see the next section for why.
polling_interval=0.5,
)api_server के अलावा capy() proxy, proxytype और useragent लेता है, साथ में सेकंड में हर कॉल का अपना timeout और polling_interval भी। user agent, अगर आप सेट करें, तो उस इकलौती रिक्वेस्ट पर भेजा जाता है जो CapSkip पज़ल लाने के लिए करता है, और इसकी ज़रूरत आपको शायद ही कभी पड़ेगी। एक version ऑप्शन भी है, लेकिन उसमें सिर्फ़ puzzle स्वीकार होता है। Capy का दूसरा परिवार, avatar, एक अलग endpoint के पीछे एक अलग challenge है, इसलिए SDK ऐसा जवाब लौटाने के बजाय, जिसे साइट ठुकरा देगी, उसे ValidationException के साथ मना कर देता है। कोई अनजान keyword, खाली key या पेज URL, या HTTP, HTTPS, SOCKS5 या SOCKS5H के अलावा कोई proxy type, कुछ भी भेजे जाने से पहले यही exception उठाता है।
Capy solve में लगभग दो सेकंड क्यों लगते हैं
पहचान अपने आप में तेज़ है। CapSkip पज़ल की तस्वीर लाता है, थोड़े से pixel गणित से तस्वीर में कटा खाँचा ढूँढता है, और ड्रैग पाथ बनाता है, और इसमें न कोई ब्राउज़र लगता है, न कोई मॉडल। फिर वह जानबूझकर इंतज़ार करता है।
Capy पज़ल जारी करने और जवाब मिलने के बीच का समय मापता है, और जो भी जवाब इतनी जल्दी आए कि कोई इंसान उतनी देर में टुकड़े को खींच ही न पाता, उसे ठुकरा देता है। Capy पर CapSkip के अपने टेस्ट के अनुसार यह निचली सीमा लगभग एक सेकंड है, और इनकार में वही संदेश आता है जो गलत जवाब पर आता है, इसलिए बहुत जल्दी पहुँचाया गया सही solve बिल्कुल खराब सॉल्वर जैसा दिखता है। इसलिए CapSkip हर Capy नतीजे को पज़ल लेने के दो सेकंड बाद तक रोके रखता है। यह इंतज़ार एक sleep है, इसलिए इसकी कीमत latency है, CPU नहीं।
डिफ़ॉल्ट सेटिंग्स में एक कॉल में चार सेकंड के क़रीब क्यों लगते हैं: SDK, CapSkip को job भेजते ही poll करता है, फिर चौथाई सेकंड बाद दोबारा, और हर बार अंतर को दोगुना करता जाता है, उसके pollingInterval तक, जो डिफ़ॉल्ट रूप से 5 सेकंड है। poll 0, 0.25, 0.75, 1.75 और 3.75 सेकंड पर होते हैं, इसलिए दो सेकंड वाला जवाब पाँचवें poll पर उठाया जाता है। कॉल पर polling_interval=0.5 के साथ, या अगर क्लाइंट ज़्यादातर Capy ही हल करता है तो constructor में pollingInterval=0.5 के साथ, कॉल job भेजे जाने के दो सेकंड से थोड़ा ही ज़्यादा समय बाद लौट आती है, हमारे टेस्ट में लगभग 2.3 सेकंड पर। फॉर्म पोस्ट करने से पहले अपनी तरफ़ से कोई देरी न जोड़ें, और ठहराव को घटाने की कोशिश न करें: यही ठहराव जवाब को पास करवाता है।
स्टेप 3: तीनों वैल्यू एक ही रिक्वेस्ट में सबमिट करें
तीनों वैल्यू उन्हीं फ़ील्ड में जाती हैं जिनमें widget उन्हें खुद फॉर्म में लिखता। उन्हें एक साथ भेजें, बाकी फॉर्म वाली उसी रिक्वेस्ट में, उसी session के ज़रिए जिससे पेज लाया गया था।
# session is the one Step 1 used, so the page's cookies go back too.
resp = session.post(
PAGE_URL, # or wherever the form's action attribute points
data={
"username": "YOUR_USERNAME",
"capy_captchakey": result["captchakey"],
"capy_challengekey": result["challengekey"],
"capy_answer": result["answer"],
},
timeout=30,
)
print(resp.status_code)जवाब को ठीक वैसे ही सबमिट करें जैसा वह लौटा है। साइट का backend इसे उस पज़ल से मिलाकर जाँचता है जो जारी हुआ था, इसलिए इसे काटना, दोबारा बनाना या किसी भी तरह साफ़-सुथरा करना इसे अमान्य कर देता है। requests library फॉर्म बॉडी को percent-encode करती है, जो ठीक है, क्योंकि सर्वर जाँचने से पहले उसे decode करता है। फिर तुरंत सबमिट करें। CapSkip हर solve के लिए एक नई challenge key बनाता है और पज़ल उसी से बँधा होता है, इसलिए key एक ही बार इस्तेमाल होती है और कम समय तक टिकती है, और एक solve से एक सबमिशन होता है।
असली फॉर्म जो भेजता है, वही दोहराएँ। ज़्यादातर पेजों में अपने hidden फ़ील्ड होते हैं, जैसे anti-forgery token, और कुछ पेज फॉर्म पोस्ट के बजाय script के ज़रिए JSON बॉडी के साथ सबमिट करते हैं। DevTools खोलकर एक बार हाथ से सबमिट करें, रिक्वेस्ट कॉपी करें, और तीनों Capy वैल्यू वहीं रखें जहाँ पेज उन्हें रखता है।
स्टेप 4: solve फेल होने पर दोबारा कोशिश
जब आप Python में Capy Puzzle किसी भी मात्रा में हल करते हैं, तो कुछ solve फेल होंगे। फेल हुआ solve एक ApiException के रूप में आता है जिसके संदेश में ERROR_CAPTCHA_UNSOLVABLE होता है, और res.php के ज़रिए, जिस endpoint पर SDK poll करता है, यह एक ही code दो अलग-अलग स्थितियों को कवर करता है। उन्हें अलग पहचानने का तरीका यह है कि वे कितनी बार होती हैं।
| क्या हुआ | कैसा दिखता है | क्या करें |
|---|---|---|
| CapSkip को खाँचा नहीं मिला | कभी-कभार, और अगली कोशिश आमतौर पर कामयाब होती है | दोबारा कोशिश करें। हर कोशिश में किसी दूसरी फ़ोटो पर बिल्कुल नया पज़ल आता है |
| Capy API ने key मना कर दी | उस एक key के लिए हर कोशिश में, और CapSkip की Capy task list में Invalid captcha key दिखता है | key और api_server जाँचें। CapSkip मना की गई key को कभी दोबारा नहीं आज़माता, क्योंकि वह उसी तरह फिर मना हो जाती |
चूक दुर्लभ होती है, इसलिए एक दोबारा कोशिश लगभग हर मामला सँभाल लेती है। CapSkip की सेटिंग्स के Capy सेक्शन में Retries सेट करें, जो डिफ़ॉल्ट रूप से 0 है और हर task के लिए तीन तक की अनुमति देता है, या अपने कोड में दोबारा कोशिश करें:
from capskip import ApiException
def solve_capy(key, url, attempts=3, **options):
for attempt in range(1, attempts + 1):
try:
return solver.capy(key, url, **options)
except ApiException as exc:
# A missed hole reads as unsolvable, and the next try
# draws a new puzzle. Anything else is final.
if "UNSOLVABLE" not in str(exc) or attempt == attempts:
raisecapy() method क्लाइंट के defaultTimeout पर poll करता है, जो 120 सेकंड है, क्योंकि Capy solve कोई ब्राउज़र session नहीं, बल्कि एक fetch और थोड़ा हिसाब भर है। CapSkip अपनी घड़ी भी चलाता है: Capy सेक्शन में कोई task 10 threads (Max. Threads) में से किसी एक के लिए 250 सेकंड (Wait Timeout) तक इंतज़ार कर सकता है, और एक कोशिश को 60 सेकंड (Row Timeout) मिलते हैं। एक सामान्य solve इन सभी सीमाओं में कई गुना आराम से समा जाता है।
एक साथ कई Capy पज़ल हल करना
Python में AsyncCapSkip कोई alias नहीं, बल्कि सचमुच का asyncio क्लाइंट है, इसलिए asyncio.gather कई solve साथ-साथ चलाता है। हर solve को उसके अपने सबमिट के साथ जोड़े रखें। पहले सौ solve इकट्ठा करना और बाद में पोस्ट करना, सबसे पहली challenge keys को तब तक पुराना होने देता है जब तक आख़िरी solve पूरे होते हैं।
import asyncio
import httpx
from capskip import AsyncCapSkip
solver = AsyncCapSkip(host="127.0.0.1", port=8080, pollingInterval=0.5)
slots = asyncio.Semaphore(10) # CapSkip's Capy Max. Threads
async def solve_and_submit(key, url, form):
# One client per job, so each form session keeps its own cookies.
async with slots, httpx.AsyncClient(
timeout=30, follow_redirects=True) as client:
await client.get(url)
result = await solver.capy(key, url)
return await client.post(url, data={
**form,
"capy_captchakey": result["captchakey"],
"capy_challengekey": result["challengekey"],
"capy_answer": result["answer"],
})
async def main(jobs):
return await asyncio.gather(
*(solve_and_submit(*job) for job in jobs), return_exceptions=True)semaphore का आकार CapSkip के thread count के बराबर है, इसलिए कोई भी job CapSkip की queue में session खोले बैठा नहीं रहता, और यह Python की standard library से आता है, जिसका दस्तावेज़ यहाँ है: asyncio.Semaphore। बड़ी मात्रा में प्रॉक्सी भी जोड़ें। हर solve, Capy API से एक नया पज़ल लेता है, और एक ही पते से ऐसे पज़ल की लगातार धारा ठीक वही पैटर्न है जिसे पकड़ने के लिए rate limiting बनी है। CapSkip के Capy सेक्शन में एक प्रॉक्सी पूल कॉन्फ़िगर करें, या हर कॉल पर type और uri वाला एक proxy dict पास करें; यह सिर्फ़ पज़ल fetch को छूता है, जो Capy solve की इकलौती रिक्वेस्ट है। asyncio के और पैटर्न यहाँ हैं: Python में समानांतर रूप से कैप्चा हल करने की गाइड.
सॉल्वर को किसी दूसरी मशीन पर चलाना
जब तक script और CapSkip एक ही Windows PC पर हों, 127.0.0.1 सही है। जैसे ही Python कोड किसी VPS, कंटेनर, CI runner या होस्टेड notebook पर जाता है, loopback गलत मशीन की ओर इशारा करता है और पहला ही solve एक NetworkException उठाता है। CapSkip को Server मोड पर कर दें और वह आपके नेटवर्क पते या पब्लिक IP पर सुनने लगता है, ताकि इनमें से कोई भी उसी API के ज़रिए उसे कॉल कर सके। जब रास्ता इंटरनेट से होकर जाए तो स्टैटिक पब्लिक IP इस्तेमाल करें, API key validation चालू करें, और Windows Firewall नियम से पोर्ट को सिर्फ़ अपेक्षित पतों तक सीमित रखें। सॉल्वर अब भी आपकी अपनी Windows मशीन है, और solve अब भी बिना मीटर वाले हैं।
SDK एनवायरनमेंट वेरिएबल खुद नहीं पढ़ता। CAPSKIP_HOST, CAPSKIP_PORT और CAPSKIP_API_KEY को अपने कोड में पढ़ें और उन्हें constructor को पास करें, जैसा पूरा उदाहरण करता है, ताकि वही script आपकी डेस्क पर भी चले और सर्वर पर भी।
पूरा चलने वाला उदाहरण
# pip install "capskip>=1.3.0" requests
import os
import re
import requests
from capskip import (ApiException, CapSkip, CapSkipError,
TimeoutException, ValidationException)
PAGE_URL = "https://example.com/login"
solver = CapSkip(
apiKey=os.getenv("CAPSKIP_API_KEY", "capskip"),
host=os.getenv("CAPSKIP_HOST", "127.0.0.1"),
port=int(os.getenv("CAPSKIP_PORT", "8080")),
# Capy answers after a two second hold; poll often enough to catch it.
pollingInterval=0.5,
)
session = requests.Session()
html = session.get(PAGE_URL, timeout=30).text
key = re.search(r"PUZZLE_[A-Za-z0-9_-]+", html)
if not key:
raise SystemExit("No PUZZLE_ key in the HTML; find it in DevTools.")
host = re.search(r"(https://[^\"'\s<>]+?)/puzzle/get_js/", html)
try:
for attempt in range(1, 4):
try:
result = solver.capy(key.group(0), PAGE_URL,
api_server=host.group(1) if host else None)
break
except ApiException as exc:
# A missed hole reads as unsolvable; the next try draws a new puzzle.
if "UNSOLVABLE" not in str(exc) or attempt == 3:
raise
print(f"attempt {attempt}: {exc}")
except ValidationException as exc:
raise SystemExit(f"not sent: {exc}")
except TimeoutException:
raise SystemExit("gave up waiting; defaultTimeout is 120 seconds")
except CapSkipError as exc:
# A third miss, a refused key, or CapSkip unreachable.
raise SystemExit(f"solve failed: {exc!r}")
# All three together, straight away: the challenge key is single-use.
resp = session.post(
PAGE_URL, # or wherever the form's action attribute points
data={
"username": "YOUR_USERNAME",
"capy_captchakey": result["captchakey"],
"capy_challengekey": result["challengekey"],
"capy_answer": result["answer"],
},
timeout=30,
)
print(resp.status_code)अगर तीनों कोशिशें फेल हों, तो सबसे पहले key देखें, क्योंकि मना की गई key हर बार एक ही तरह फेल होती है, जबकि चूक लगभग कभी लगातार तीन बार नहीं होती। जब पेज widget को किसी bundled script से बनाता है और regex को कुछ नहीं मिलता, तो Network टैब खोलें और key और host को widget की अपनी रिक्वेस्ट से कॉपी करें। इस method के पीछे का raw endpoint यहाँ दर्ज है: API रेफ़रेंस का Capy सेक्शन.
आम errors और उनका मतलब
| आप जो देखते हैं | कारण | फिक्स |
|---|---|---|
| capy() के तीनों वैल्यू लौटाने के बावजूद साइट सबमिट ठुकरा देती है | जवाब बदल दिया गया, या वैल्यू में से सिर्फ़ एक या दो ही फॉर्म तक पहुँचीं | result["answer"] को हूबहू, बाकी दो वैल्यू के साथ, एक ही रिक्वेस्ट में पोस्ट करें |
| साइट सबमिट ठुकरा देती है और कहती है कि session expire हो गया | पेज requests.get() से लाया गया और फॉर्म एक नई रिक्वेस्ट से भेजा गया, इसलिए पेज की cookies कभी वापस नहीं पहुँचीं | पेज लाना और फॉर्म पोस्ट करना, दोनों एक ही requests.Session से करें |
| एक बार चल चुका सबमिट दूसरी कोशिश में फेल हो जाता है | challenge key एक ही बार इस्तेमाल होती है और कम समय तक टिकती है | हर सबमिशन के लिए दोबारा हल करें, और तुरंत सबमिट करें |
| एक ही key के लिए हर कोशिश पर एक ApiException | Capy API ने key मना कर दी, या api_server गलत host की ओर इशारा करता है | key को prefix समेत दोबारा कॉपी करें, और script टैग का host जाँचें |
| कभी-कभार आने वाला ApiException, जिसमें ERROR_CAPTCHA_UNSOLVABLE होता है | CapSkip उस पज़ल में खाँचा नहीं ढूँढ पाया | दोबारा कोशिश करें; अगली कोशिश में दूसरा पज़ल आता है |
| किसी दूसरी सर्विस से सैंपल कॉपी करने के बाद हर solve फेल होता है | सैंपल api_server को api.capy.me पर सेट करता है, जो अब resolve नहीं होता | यह ऑप्शन हटा दें और डिफ़ॉल्ट host इस्तेमाल करें |
| कुछ भी भेजे जाने से पहले ही ValidationException | खाली key या पेज URL, version के रूप में avatar, HTTP, HTTPS, SOCKS5 या SOCKS5H के अलावा कोई proxy type, या ऐसा keyword जो यह method नहीं लेता | पक्का करें कि key खाली स्ट्रिंग नहीं है, और संदेश में बताए गए argument को ठीक करें या हटा दें |
| ERROR_WRONG_USER_KEY या ERROR_KEY_DOES_NOT_EXIST वाला ApiException | CapSkip में API key validation चालू है, और script ने डिफ़ॉल्ट key भेजी या कोई key नहीं भेजी | CAPSKIP_API_KEY को CapSkip में कॉन्फ़िगर की गई किसी key पर सेट करें |
| भारी parallel लोड में TimeoutException | queue में उससे ज़्यादा jobs हैं जितने 10 threads 120 सेकंड के भीतर निपटा सकते हैं, या solve के बीच में CapSkip रीस्टार्ट हो गया | semaphore से concurrency सीमित करें, या defaultTimeout बढ़ाएँ |
| पहली कॉल पर एक NetworkException | CapSkip चल नहीं रहा, या host और port गलत हैं | CapSkip शुरू करें, फिर देखें कि उसे Local मोड में होना चाहिए या Server मोड में |
FAQ
capy() एक token के बजाय तीन वैल्यू क्यों लौटाता है?
क्योंकि Capy फॉर्म यही पोस्ट करता है। किसी भी मोड़ पर कोई सर्वर token जारी नहीं करता। widget खुद एक challenge key बनाता है, उससे जुड़ा पज़ल लाता है और ड्रैग रिकॉर्ड करता है, और फिर साइट challenge key और जवाब को अपनी private key के साथ Capy को भेजती है ताकि उनकी जाँच हो सके। CapSkip widget की भूमिका निभाता है, इसलिए वह वही लौटाता है जो widget फॉर्म में लिखता।
क्या python-requests user agent की वजह से जवाब ठुकरा दिया जाता है?
Capy की तरफ़ से नहीं। Capy का जवाब किसी ब्राउज़र से बँधा नहीं होता, CapSkip इसके लिए कोई user agent नहीं लौटाता, और जो वैकल्पिक user agent आप पास कर सकते हैं, वह सिर्फ़ पज़ल लाने वाली रिक्वेस्ट को बदलता है। फिर भी साइट खुद, अपनी वजहों से, ऐसी रिक्वेस्ट ठुकरा सकती है जो खुद को python-requests बताती हो। अगर ऐसा हो, तो session पर एक बार किसी ब्राउज़र का User-Agent सेट कर दें, और उससे जाने वाली हर रिक्वेस्ट, सबमिट समेत, वही header ले जाएगी।
क्या मैं जवाब को Selenium या Playwright session में इस्तेमाल कर सकता हूँ?
हाँ। ब्राउज़र में खुले पेज के URL के साथ हल करें, फिर एक छोटी script से तीनों वैल्यू फॉर्म के capy_captchakey, capy_challengekey और capy_answer hidden inputs में लिखें, और जो input widget ने अभी तक नहीं बनाया, उसे जोड़ दें, फिर फॉर्म को वैसे ही सबमिट करें जैसे पेज आमतौर पर करता। साथ में ब्राउज़र में टुकड़े को ड्रैग न करें, क्योंकि उससे एक दूसरा, अलग जवाब बन जाएगा। अगर ब्राउज़र सिर्फ़ पज़ल पार करने के लिए है, तो ऊपर वाला requests रास्ता ज़्यादा आसान और तेज़ है।
क्या किसी होस्टेड प्लेटफ़ॉर्म पर चल रही Python script सॉल्वर तक पहुँच सकती है?
हाँ। कनेक्शन सेटिंग्स में CapSkip को Server मोड पर कर दें ताकि वह loopback के बजाय किसी नेटवर्क पते पर सुने, वह पता अपनी script में CAPSKIP_HOST से पढ़ें, और उसे CapSkip() को पास करें। VPS, कंटेनर होस्ट, CI runner और होस्टेड notebook, सब उसी HTTP API के ज़रिए जुड़ते हैं। जब रास्ता इंटरनेट से होकर जाए, तो स्टैटिक पब्लिक IP और फ़ायरवॉल नियम इस्तेमाल करें। सॉल्वर आपके अपने हार्डवेयर पर ही रहता है, इसलिए solve गिनने के तरीके में कुछ नहीं बदलता। यही flow .NET में यहाँ कवर किया गया है: C# Capy Puzzle गाइड.
संक्षेप में
Python में Capy Puzzle हल करने के लिए, पेज को requests session से लाएँ, एक regex से PUZZLE_ key निकालें, और widget script का host नोट कर लें, कहीं वह डिफ़ॉल्ट न हो। solver.capy() को key और असली पेज URL के साथ कॉल करें और उसे अपने कुछ सेकंड लेने दें, polling_interval=0.5 के साथ लगभग 2.3 सेकंड। captchakey, challengekey और answer को तीनों capy_ फ़ील्ड में पोस्ट करें, हूबहू, एक साथ और तुरंत, उसी session से। कभी-कभार की चूक पर दोबारा कोशिश करें, volume बढ़ने के साथ प्रॉक्सी जोड़ें, और जैसे ही script सॉल्वर की मशीन से बाहर जाए, Server मोड पर चले जाएँ।
- यह टाइप कैसे काम करता है और सॉल्वर क्या-क्या कवर करता है: Capy Puzzle सॉल्वर पेज.
- कैप्चा के वे सभी टाइप जिन्हें Python पैकेज संभालता है: Python कैप्चा सॉल्वर पेज.
उस दोबारा कोशिश के बारे में एक आख़िरी बात। हर कोशिश में एक अलग पज़ल आता है, इसलिए चूक का सही इलाज दोबारा कोशिश करना ही है, और अपनी ही मशीन पर चलने वाले असीमित कैप्चा सॉल्वर के साथ दूसरी कोशिश की कीमत बस कुछ सेकंड होती है, एक और बिल किया गया solve नहीं।
