Python में DataDome कैप्चा कैसे हल करें (requests)

datadome captcha in python - How to Solve DataDome CAPTCHA in Python (requests)

Python में DataDome कैप्चा हल करने के लिए आप 403 ब्लॉक पेज पढ़ते हैं, उससे चैलेंज का पता बनाते हैं, और उसे CapSkip DataDome सॉल्वर को datadome() के साथ भेजते हैं, फिर मिली cookie के साथ अपनी रिक्वेस्ट दोहराते हैं। जवाब एक cookie है, फ़ॉर्म के लिए कोई टोकन नहीं, और CapSkip के दस्तावेज़ कहते हैं कि वह सिर्फ़ उसी User-Agent और उसी IP पते के साथ काम करती है जिसके साथ वह मिली थी। यह गाइड CapSkip Python SDK और requests के साथ पूरा loop करीब 90 लाइनों में चलाती है। CapSkip आपके अपने Windows PC पर चलता है और प्रति-हल कोई शुल्क नहीं लगता, इसलिए दोबारा कोशिश करने में कुछ खर्च नहीं होता।

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

  • CapSkip 3.2.0 या बाद का, जो किसी Windows PC पर चल रहा हो। उस रिलीज़ में स्लाइडर और डिवाइस चेक के लिए DataDome हल करने की सुविधा जुड़ी थी। पहली बार शुरू करने के चरण सेटअप गाइड में समझाए गए हैं।
  • Python 3.10 या बाद का और capskip पैकेज का वर्ज़न 1.5.0 या बाद का। पुराने वर्ज़न में datadome method नहीं है। नीचे का कोड Python 3.11.7 और 3.14.0 पर capskip 1.5.0 और requests 2.34.2 के साथ चला। Python 3.10 यहाँ आज़माया नहीं गया।
  • एक PowerShell prompt। कमांड PowerShell syntax में लिखी गई हैं।
  • ऐसा पेज जो आपका अपना हो या जिसे ऑटोमेट करने की आपको अनुमति हो, और जो DataDome के पीछे हो।
  • सॉल्वर के लिए एक पता। Local मोड में CapSkip केवल उसी डिवाइस के लिए 127.0.0.1 पर जवाब देता है। Server मोड में वह आपके नेटवर्क पते या पब्लिक IP पर सुनता है, ताकि किसी दूसरे PC, VPS या होस्टेड प्लेटफ़ॉर्म पर चल रही script API के ज़रिए उसे कॉल कर सके। दोनों यहाँ सेट किए जाते हैं: कनेक्शन सेटिंग्स.
  • टेस्टिंग से आगे बढ़ने पर हर टास्क के लिए एक sticky proxy (जो पूरे टास्क में एक ही IP पता बनाए रखे)। cookie उस IP पते से बँधी होती है जिससे वह मिली थी, जिसे चरण 3 समझाता है।

यह कैसे टेस्ट किया गया: कोड तीन mock सर्वर के सामने चला जो मैंने खुद लिखे थे (यानी टेस्ट के लिए बनाए नकली सर्वर), किसी असली DataDome साइट के सामने नहीं। उनमें से एक उन जाँचों की नक़ल करता है जो CapSkip के API दस्तावेज़ के DataDome सेक्शन में सूचीबद्ध हैं, दूसरा एक संरक्षित साइट की भूमिका निभाता है जो 403 ब्लॉक पेज देती है और सिर्फ़ वही cookie स्वीकार करती है जो CapSkip ने जारी की हो, उसी User-Agent के साथ जिसके लिए वह जारी हुई थी, और तीसरा forward proxy की भूमिका निभाता है। SDK असली capskip 1.5.0 था। CapSkip app मेरे PC पर चल नहीं रहा था, इसलिए यहाँ कुछ नहीं दिखाता कि असली हल में कितना समय लगता है या कोई असली DataDome साइट क्या स्वीकार करती है। cookie के नियम CapSkip के दस्तावेज़ों से आते हैं। DataDome के अपने cookie दस्तावेज़ के अनुसार datadome cookie एक साल चलती है, और उसके Domain या Path को बदलने से आगाह किया गया है। यह नहीं बताया गया कि cookie किससे बँधी है।

चरण 1: ब्लॉक पेज पढ़ें और captcha_url बनाएँ

जब DataDome को किसी रिक्वेस्ट पर शक होता है, तो साइट कंटेंट की जगह status 403, कभी-कभी 401, और एक छोटा HTML पेज लौटाती है। उस पेज में dd नाम का एक script object होता है और वह geo.captcha-delivery.com से एक iframe में चैलेंज लोड करता है। CapSkip को iframe का वही पता चाहिए, और दस्तावेज़ उसे captcha_url कहते हैं। अगर पेज में iframe पहले से मौजूद है, तो आप उसका src जैसा है वैसा ले सकते हैं। ज़्यादातर ब्लॉक पेज iframe को script से बनाते हैं, इसलिए नीचे की function dd object से वही पता जोड़कर बनाती है।

rt की value रास्ता तय करती है। c का मतलब /captcha/ के नीचे का स्लाइडर है और i का मतलब /interstitial/ के नीचे का डिवाइस चेक। t की value भी मायने रखती है: fe एक चैलेंज है, और bv का मतलब है कि पेज लाने वाले IP पते को DataDome ने बैन कर दिया है। पहली रिक्वेस्ट सादे Chrome User-Agent के साथ जाती है। वह string कभी CapSkip को नहीं भेजी जाती, इसलिए उसके Chrome वर्ज़न का किसी चीज़ से मेल खाना ज़रूरी नहीं। मैंने यह नहीं आज़माया कि कोई असली DataDome साइट किसी दूसरे User-Agent को वही चैलेंज देती है या नहीं, इसलिए इस हिस्से को बिना परखा हुआ मानें।

# pip install capskip requests
import json
import re
from urllib.parse import urlencode

import requests

PAGE_URL = "https://www.example.com/"  # a page behind DataDome
BROWSER = {  # for the first request only; the cookie comes with its own User-Agent
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/156.0.0.0 Safari/537.36",
}


def get(headers, via=None):
    proxies = {"http": via, "https": via} if via else None
    return requests.get(PAGE_URL, headers=headers, proxies=proxies, timeout=30)


def captcha_url_from(resp):
    """Build the challenge address from a DataDome block page, or None."""
    if resp.status_code not in (401, 403):
        return None
    found = re.search(r"var\s+dd\s*=\s*(\{[^}]*\})", resp.text)
    if not found:
        return None
    dd = json.loads(found.group(1).replace("'", '"'))
    path = "interstitial" if dd["rt"] == "i" else "captcha"
    query = {"initialCid": dd["cid"], "hash": dd["hsh"], "cid": dd["cookie"]}
    if dd.get("t"):
        query["t"] = dd["t"]  # fe is a challenge, bv means the address is banned
    query.update(referer=PAGE_URL, s=dd["s"])
    for key in ("e", "b"):
        if dd.get(key):
            query[key] = dd[key]
    query["dm"] = "cd"
    return f"https://{dd.get('host', 'geo.captcha-delivery.com')}/{path}/?{urlencode(query)}"

function किसी भी ऐसे response के लिए None लौटाती है जो ब्लॉक पेज नहीं है, ताकि script “हल करने को कुछ नहीं” और “हल हो गया” में फ़र्क़ कर सके। हर ब्लॉक पेज एक नया चैलेंज होता है। उसके captcha_url का जल्दी इस्तेमाल करें, और अगले टास्क के लिए पुराने पते को दोबारा इस्तेमाल करने के बजाय पेज फिर से रिक्वेस्ट करें।

चरण 2: datadome() से हल करें

SDK का method datadome(captcha_url, pageurl, userAgent, proxy) है, जो 2Captcha के argument क्रम का पालन करता है। पहले दो ज़रूरी हैं। CapSkip में userAgent और proxy वैकल्पिक हैं। अगर आप कोई User-Agent नहीं भेजते, तो CapSkip अपने ब्राउज़र वाला इस्तेमाल करता है और उसे नतीजे में userAgent के रूप में लौटाता है। अगर आप भेजते हैं, तो वह CapSkip के ब्राउज़र के ही major वर्ज़न वाला Windows के लिए Chrome होना चाहिए, इसलिए उसे छोड़ देना आसान चुनाव है। method 300 सेकंड के उस लंबे timeout के साथ इंतज़ार करता है जो reCAPTCHA इस्तेमाल करता है, क्योंकि CapSkip चैलेंज को असली ब्राउज़र में पास करता है। API दस्तावेज़ कहते हैं कि एक हल में आम तौर पर 3 से 20 सेकंड लगते हैं, और मैंने किसी का समय नहीं नापा।

proxy वही है जिससे आपकी बाद की रिक्वेस्ट जाएँगी। अगर आपकी script proxy से होकर जाती है तो उसे दें, और अगर रिक्वेस्ट उसी मशीन से निकलती हैं जिस पर CapSkip चलता है तो कुछ न दें। अगर CapSkip किसी server पर चल रहा है, तो वह मशीन वही server है।

from capskip import CapSkip

# Local mode. In Server mode, use your server's address instead.
solver = CapSkip(host="127.0.0.1", port=8080)


def proxy_arg(proxy_url):
    if not proxy_url:
        return None  # your requests leave from the PC that runs CapSkip
    scheme, rest = proxy_url.split("://", 1)
    return {"type": scheme.upper(), "uri": rest}  # e.g. HTTP, user:pass@ip:port


def solve(captcha_url, proxy_url=None):
    # No userAgent argument: CapSkip uses its own browser's and reports it.
    return solver.datadome(captcha_url, PAGE_URL, proxy=proxy_arg(proxy_url))

अगर डिवाइस चेक पास नहीं हो पाता, तो DataDome स्लाइडर पर चला जाता है। CapSkip के दस्तावेज़ों के अनुसार वही एक call उसके पीछे वहाँ तक जाती है, इसलिए दोनों चैलेंज के लिए अलग कोड की ज़रूरत नहीं।

चरण 3: cookie को उसके User-Agent और IP पते के साथ भेजें

नतीजा एक dictionary है जिसके चार फ़ील्ड मायने रखते हैं। code फ़ील्ड वह cookie है जैसी DataDome ने सेट की थी, Max-Age, Domain और बाकी attributes के साथ, और cookie jar को यही चाहिए। cookie फ़ील्ड सिर्फ़ datadome नाम और value की जोड़ी है, और Cookie header को यही चाहिए। userAgent फ़ील्ड वह User-Agent है जिसके साथ वह मिली थी। proxy फ़ील्ड तभी आता है जब आपने कोई proxy नहीं भेजा और CapSkip ने अपनी DataDome proxy list से हल किया। CapSkip के दस्तावेज़ कहते हैं कि DataDome cookie को किसी दूसरे IP पते से या दूसरे User-Agent के साथ ठुकरा देता है, इसलिए हर बार वही User-Agent भेजें, और जब नतीजा किसी proxy का नाम दे, तो रिक्वेस्ट उसी से भेजें। वह proxy फ़ील्ड सिर्फ़ host और port है, बिना scheme और बिना login के। function http:// जोड़ देती है और इस तरह मान लेती है कि list proxy को login नहीं चाहिए। अगर आपकी proxy को चाहिए, तो उसे जोड़ें।

DataDome बाद के किसी response में बदली हुई cookie भी भेज सकता है। function सबसे नई वाली रखती है, जैसे ब्राउज़र रखता।

def send_with_cookie(result, proxy_url=None):
    # The cookie works only from the address and User-Agent that earned it.
    via = proxy_url
    if not via and result.get("proxy"):
        via = "http://" + result["proxy"]  # CapSkip solved through its own list
    headers = {"User-Agent": result["userAgent"], "Cookie": result["cookie"]}
    resp = get(headers, via)
    fresh = resp.cookies.get("datadome")  # DataDome may rotate the cookie
    if fresh:
        headers["Cookie"] = f"datadome={fresh}"
    return resp, headers, via

cookie को header में हाथ से सेट किया गया है, इसलिए requests उसे आपके लिए नहीं सँभालता। यह जान-बूझकर है: साफ़ तौर पर लिखा header session jar पर भारी पड़ता है, और cookie, User-Agent और proxy एक ही जगह साथ रहते हैं। proxy वाले रन ने एक बात दिखाई: scheme के बाद का text CapSkip को वैसे ही जाता है जैसा आपने लिखा, इसलिए proxy login में ऐसे अक्षर न रखें जिन्हें percent-encoding चाहिए। socks5 proxy के लिए requests को उसका socks extra भी चाहिए, जो pip install requests[socks] से इंस्टॉल होता है।

चरण 4: पूरा काम करने वाला उदाहरण

आख़िरी ब्लॉक Python में DataDome CAPTCHA का पूरा flow जोड़ता है और retry भी जोड़ता है। चारों ब्लॉक datadome_demo.py नाम की एक ही फ़ाइल में एक के बाद एक सेव करें और python datadome_demo.py से चलाएँ। हर कोशिश पेज को दोबारा रिक्वेस्ट करती है, इसलिए हर बार नया चैलेंज साथ जाता है। नाकाम हल ApiException उठाता है और loop दोबारा कोशिश करता है। जिस cookie पर फिर भी 403 मिले, वह भी loop को नए ब्लॉक पेज के साथ दोबारा घुमा देती है।

from capskip import ApiException


def fetch_protected(proxy_url=None):
    for attempt in range(1, 4):
        resp = get(BROWSER, proxy_url)  # a fresh block page, a fresh challenge
        captcha_url = captcha_url_from(resp)
        if captcha_url is None:
            return resp, BROWSER, proxy_url  # no block page on this response
        try:
            result = solve(captcha_url, proxy_url)
        except ApiException as err:
            print(f"attempt {attempt}: {err}")  # the next attempt gets a new page
            continue
        resp, headers, via = send_with_cookie(result, proxy_url)
        if resp.status_code != 200:
            print(f"attempt {attempt}: HTTP {resp.status_code} with the cookie")
            continue
        return resp, headers, via
    raise RuntimeError("DataDome not passed in 3 attempts")


if __name__ == "__main__":
    page, headers, via = fetch_protected()
    print(page.status_code, page.text[:40])
    again = get(headers, via)  # reuse the cookie while it lasts
    print(again.status_code)

SDK captcha_url को t=bv के साथ कुछ भी भेजने से पहले ही ठुकरा देता है, क्योंकि उस पते से कोई हल पास नहीं हो सकता। वह ValidationException एक ApiException नहीं है, इसलिए loop उसे नहीं पकड़ता। उसे सामने आने दें: यह संकेत है कि पता बदलकर फिर से शुरू करें। CapSkip जिस बैन को ERROR_PROXY_BANNED के रूप में बताता है, वह ApiException बनकर आता है और loop उसे उसी पते पर दोबारा आज़माता है, इसलिए अगर आउटपुट में वह error दिखे, तो proxy बदलकर ही दोबारा चलाएँ। proxy rotation गाइड में proxies को बारी-बारी से बदलने का तरीका है, और CAPTCHA और ब्लॉक में फ़र्क़ पहचानने वाली गाइड में वह दूसरा मामला बताया गया है जहाँ पेज चैलेंज है ही नहीं।

mock रन में script ने इस तरह व्यवहार किया:

mock सेटिंगscript ने क्या किया
स्लाइडर ब्लॉक पेज, हर हल का जवाब दिया गयाएक टास्क, फिर cookie के साथ status 200, और दोबारा इस्तेमाल पर फिर 200
डिवाइस चेक ब्लॉक पेजवही कोड चला: captcha_url /interstitial/ की ओर था और नतीजा वही रहा
पहले दो हल ठुकराए गएदो attempt लाइनें, फिर तीसरे टास्क पर status 200
पहले तीन हल ठुकराए गएतीन attempt लाइनें, फिर RuntimeError
नतीजा एक proxy का नाम देता है, जैसा CapSkip की अपनी list करती हैcookie वाली रिक्वेस्ट उसी proxy से गई और 200 मिला
आपका अपना proxy, जो हल को दिया गयाin.php को proxy और उसका type मिला, और रिक्वेस्ट उसी से गईं
t=bv वाला ब्लॉक पेजValidationException, और mock CapSkip को कोई रिक्वेस्ट मिली ही नहीं
cookie दूसरे User-Agent के साथ भेजी गईmock साइट ने 403 दिया
cookie दूसरे IP पते से भेजी गईmock साइट ने उस cookie पर 403 दिया जो CapSkip ने proxy से जारी की थी और जो उसके बिना भेजी गई

आख़िरी दो पंक्तियाँ मेरे mock के नियमों को जाँचती हैं, जो CapSkip के दस्तावेज़ों का पालन करते हैं। ये असली service के बारे में कोई सबूत नहीं हैं।

आम errors

त्रुटिकारणफिक्स
ValidationExceptionऐसा captcha_url जो DataDome का चैलेंज पता नहीं है, t=bv वाला ब्लॉक पेज, ऐसा pageurl जो http या https नहीं है, या ऐसा userAgent जो Windows के लिए Chrome नहीं है। संदेश बताता है कि इनमें से कौन-सा हैताज़ा ब्लॉक पेज से पता दोबारा बनाएँ, अगर IP पता बैन हो तो उसे बदलें, और userAgent argument हटा दें
ApiException, ERROR_WRONG_USERAGENT के साथUser-Agent Windows के लिए Chrome है, पर उसका major वर्ज़न CapSkip के ब्राउज़र से अलग हैuserAgent न भेजें और नतीजे में जो बताया जाए वही इस्तेमाल करें
ERROR_CAPTCHA_UNSOLVABLE वाला ApiExceptionचैलेंज पास नहीं हुआपेज को फिर से रिक्वेस्ट करें और उसका नया captcha_url सबमिट करें
ApiException, ERROR_PROXY_BANNED के साथCapSkip ऐसे टास्क को ठुकरा देता है जिसका ब्लॉक पेज t=bv बताता है, API दस्तावेज़ों के अनुसारproxy बदलें और पेज को फिर से रिक्वेस्ट करें
ApiException, ERROR_PROXY_CONNECT_REFUSED के साथCapSkip इसे तब बताता है जब वह proxy के ज़रिए कनेक्ट नहीं हो पाता। मैंने इसे दोहराया नहींproxy का पता, login और type जाँचें
TimeoutExceptionCapSkip ने 300 सेकंड के इंतज़ार में कोई जवाब नहीं दिया। यह ApiException नहीं है, इसलिए loop इसे नहीं पकड़ताजाँचें कि CapSkip चल रहा है और हल कर रहा है, फिर script को दोबारा चलाएँ
NetworkExceptionCapSkip चल नहीं रहा, या host या port गलत हैCapSkip शुरू करें और कनेक्शन सेटिंग्स जाँचें, फिर यह देखें:
cookie के साथ भी 403 आ रहा हैरिक्वेस्ट किसी दूसरे IP पते से निकली, दूसरा User-Agent इस्तेमाल हुआ, या cookie की अवधि खत्म हो गईहर बार नतीजे का userAgent और proxy भेजें, या नए ब्लॉक पेज के साथ loop फिर से चलाएँ

सॉल्वर को किसी server पर चलाना

script को CapSkip से दो चीज़ें चाहिए: एक host और एक port। Local mode में वह 127.0.0.1 और आपका अपना PC है। Server mode में CapSkip आपके नेटवर्क पते या पब्लिक IP पर सुनता है, ताकि किसी दूसरे PC, VPS या hosted platform पर चल रही script उसी API के ज़रिए उसे कॉल कर सके। CapSkip constructor में host और port बदलें, कोड में और कुछ नहीं बदलता। स्थिर रिमोट एक्सेस के लिए स्टैटिक पब्लिक IP सुझाया जाता है। Server mode फिर भी आपका अपना हार्डवेयर है और फिर भी बिना किसी प्रति-हल शुल्क के है। यह पोर्ट को किसी भी पते के लिए खोल देता है, इसलिए जिन पतों को वहाँ तक नहीं पहुँचना चाहिए उनके लिए Windows Firewall का block rule जोड़ें। याद रखें कि हल उसी मशीन पर चलता है, इसलिए cookie उस server के IP पते से मिलती है। जब तक आप proxy नहीं देते, cookie ले जाने वाली रिक्वेस्ट को भी उसी server से निकलना होगा। proxy दें तो हल और अपनी रिक्वेस्ट, दोनों को वही दें। मोड कैसे बदलें, यह कनेक्शन सेटिंग्स में दिखाया गया है।

FAQ

क्या DataDome सॉल्वर टोकन लौटाता है?

नहीं। वह datadome cookie लौटाता है। आप उस cookie को उस रिक्वेस्ट के Cookie header में भेजते हैं जो ब्लॉक हुई थी, उसी User-Agent के साथ। भरने के लिए कोई फ़ॉर्म फ़ील्ड नहीं है।

क्या DataDome के लिए proxy चाहिए?

टेस्ट के लिए नहीं। पहले रन के लिए एक IP पता काफ़ी है। CapSkip के दस्तावेज़ों के अनुसार cookie सिर्फ़ उसी IP पते से काम करती है जिससे वह मिली थी, इसलिए जब आप कई रिक्वेस्ट भेजें, तो हर टास्क के लिए एक sticky proxy रखें और वही proxy हल को और अपनी रिक्वेस्ट को दें।

क्या यह स्लाइडर और डिवाइस चेक, दोनों के लिए काम करता है?

हाँ, उसी call से। स्लाइडर का captcha_url /captcha/ के नीचे होता है और डिवाइस चेक का /interstitial/ के नीचे। CapSkip के दस्तावेज़ कहते हैं कि जो डिवाइस चेक स्लाइडर तक बढ़ जाता है, उसे भी वहाँ तक फ़ॉलो किया जाता है।

क्या कोई hosted platform इसे आपके CapSkip के सामने चला सकता है?

हाँ, Server mode के ज़रिए। CapSkip को अपने नेटवर्क या पब्लिक IP पर सुनने के लिए सेट करें, CapSkip constructor को उसी host और port पर पॉइंट करें, और loop वैसे ही काम करता है, बस एक बदलाव के साथ: हल अब server पर चलता है, इसलिए हल को और अपनी रिक्वेस्ट को वही proxy दें। सॉल्वर आपके हार्डवेयर पर ही रहता है।

संक्षेप में

Python में DataDome CAPTCHA हल करने में चार काम होते हैं: ब्लॉक पेज पढ़ें, captcha_url बनाएँ, datadome() को call करें, और cookie, उसके User-Agent और IP पते के साथ रिक्वेस्ट दोहराएँ। अपनी मशीन पर दोबारा कोशिश मुफ़्त है, और जब कोई संरक्षित साइट बार-बार नए चैलेंज थमाती रहे, तो आप यही अपने Windows PC पर चल रहे लोकल captcha सॉल्वर से पाना चाहते हैं। SDK की बाकी जानकारी के लिए देखें: Python कैप्चा सॉल्वर पेज.