Scarnox · Blog

Captcha token expired: कारण और इसे कैसे ठीक करें

Captcha token एक अल्पकालिक प्रमाण है कि challenge पास हुआ था। Scarnox के PopularCaptcha tokens जारी होने के लगभग दो मिनट बाद expire हो जाते हैं। अगर आप उस window के बाद token submit करते हैं, तो site form को reject कर देती है, अक्सर यह संदेश दिखाकर कि captcha expire हो गया है या अमान्य है। समाधान लगभग हमेशा समय का मामला होता है: solve को submit के जितना हो सके पास रखें, हर token एक बार इस्तेमाल करें, और retry तभी करें जब पक्का हो कि पहला प्रयास स्वीकार नहीं हुआ।

Tokens क्यों expire होते हैं

Token स्थायी credential नहीं है। Site जानना चाहती है कि कोई इंसान (या उसकी ओर से काम करने वाला solver) challenge हाल ही में पूरा कर चुका है, इसलिए वह token को छोटी उम्र देती है। घड़ी token जारी होने पर शुरू होती है, न कि जब आप पहली बार API call करते हैं। Solve और submit के बीच जो भी होता है, वह दो मिनट में से खर्च होता है।

आम कारण

समाधान: submit से ठीक पहले solve करें

सबसे सरल भरोसेमंद पैटर्न है solve और submit को एक कदम बनाना। Token माँगें, उसे form में डालें, form post करें, और बीच में कुछ धीमा न करें:

import requests

API_KEY = "scarnox_YOURAPIKEY"
CREATE_URL = "https://api.scarnox.com/api/tasks/create"

def fresh_token(sitekey: str, page_url: str) -> str:
    r = requests.post(
        CREATE_URL,
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={
            "captcha_type": "PopularCaptchaTaskProxyless",
            "site_key": sitekey,
            "site_url": page_url,
        },
        timeout=185,  # token तैयार होने तक call रुकती है
    )
    data = r.json()
    if data.get("errorId") != 0:
        raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
    return data["solution"]["token"]

def submit_form(page_url: str, sitekey: str, form: dict) -> requests.Response:
    token = fresh_token(sitekey, page_url)  # post से ठीक पहले solve करें
    return requests.post(
        page_url,
        data={**form, "h-captcha-response": token, "g-recaptcha-response": token},
        timeout=30,
    )

ध्यान दें कि submit_form token को cache या queue में नहीं रखता। वह एक माँगता है, उसे post करता है, और आगे बढ़ जाता है। विफल solves का चार्ज नहीं लगता, इसलिए विफल request की solve-side पर कोई कीमत नहीं।

सुरक्षित रूप से retry करें

कुछ sites expire हुए token को साफ़ response से reject करती हैं। दूसरी sites एक सामान्य page लौटाती हैं जिसमें अंदर एक error संदेश होता है, इसलिए अकेला status code कुछ नहीं बताता। जिस response को site expire हुए token के लिए असल में लौटाती है, उसे देखें और अपनी जाँच उसी पर बनाएँ। Retry loop ऐसा दिख सकता है:

def submit_with_retry(page_url: str, sitekey: str, form: dict, attempts: int = 2):
    for _ in range(attempts):
        resp = submit_form(page_url, sitekey, form)
        if resp.status_code < 400 and "captcha" not in resp.text.lower():
            return resp  # स्वीकार हुआ, इस site के response के अनुसार
    raise RuntimeError("captcha token rejected after retries")

ऐसे forms पर retry सावधानी से करें जो कुछ बनाते हैं। अगर पहला प्रयास सचमुच स्वीकार हो गया था, पर आपके code ने response गलत पढ़ा, तो retry एक duplicate account, order या message बना सकता है। केवल तभी retry करें जब आप पक्के हों कि पहली post स्वीकार नहीं हुई, और जाँच उसी site के लिए विशिष्ट बनाएँ जिस पर आप काम कर रहे हैं।

समय को ईमानदार रखें

आम गलतियाँ

पर्याप्त लॉग रखें ताकि कारण पता चले

जब submit विफल हो, तो token जारी होने का समय, form post होने का समय, HTTP status और response के पहले कुछ सौ अक्षर रिकॉर्ड करें। इन चार मानों से आप एक नज़र में बता सकते हैं कि token expire हुआ या site ने किसी और कारण से reject किया। साझा logs में पूरा token न लिखें, क्योंकि एक वैध token उस एक challenge के लिए credential है।

अगर अब भी विफल हो तो क्या जाँचें

  1. Token मिलने और form post के बीच का समय प्रिंट करें।
  2. पक्का करें कि site_url उस page से मेल खाता है जिस पर captcha दिखता है।
  3. पक्का करें कि sitekey मौजूदा page से पढ़ी गई है, पुरानी copy से नहीं।
  4. Form field के नाम जाँचें। PopularCaptcha tokens h-captcha-response में जाते हैं, और अक्सर g-recaptcha-response में भी।

सभी error responses और हर एक को संभालने का पूरा तरीका captcha solver error handling में है।

अगले कदम