Python ile DataDome CAPTCHA Nasıl Çözülür (requests)

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

Python’da bir DataDome CAPTCHA’sını çözmek için 403 engelleme sayfasını okuyup, ondan challenge adresini oluşturup, bu adresi CapSkip DataDome çözücüsü üzerinden datadome() ile gönderip, döndürdüğü çerezle isteğinizi yinelersiniz. Yanıt bir çerezdir, bir form için token değildir ve CapSkip belgeleri, çerezin yalnızca kazanıldığı User-Agent ve IP adresiyle çalıştığını söyler. Bu rehber, bütün döngüyü CapSkip Python SDK ve requests ile yaklaşık 90 satırda çalıştırır. CapSkip, çözüm başına ücret olmadan kendi Windows bilgisayarınızda çalışır; bu yüzden bir yeniden deneme hiçbir şeye mal olmaz.

Neye ihtiyacınız var

  • Bir Windows bilgisayarında çalışan CapSkip 3.2.0 veya üzeri. Bu sürüm, kaydırıcı ve cihaz kontrolü için DataDome çözme desteğini ekledi. İlk başlatmayı kurulum kılavuzu adım adım anlatır.
  • Python 3.10 veya üzeri ve capskip paketinin 1.5.0 veya üzeri sürümü. Daha eski sürümlerde datadome metodu yoktur. Aşağıdaki kod, capskip 1.5.0 ve requests 2.34.2 ile Python 3.11.7 ve 3.14.0 üzerinde çalıştı. Python 3.10 burada denenmedi.
  • Bir PowerShell istemi. Komutlar PowerShell sözdizimini kullanır.
  • Sahibi olduğunuz ya da otomatikleştirmenize izin verilen, DataDome arkasındaki bir sayfa.
  • Çözücü için bir adres. Local modunda CapSkip 127.0.0.1 üzerinden yalnızca o cihaza yanıt verir. Server modunda ağ adresinizi veya genel IP’nizi dinler, böylece başka bir bilgisayardaki, bir VPS’teki veya barındırılan bir platformdaki script API üzerinden ona erişebilir. İkisi de şurada ayarlanır: bağlantı ayarları.
  • Test aşamasını geçtiğinizde görev başına sabit IP’li (sticky) bir proxy. Çerez, onu kazanan IP adresine bağlıdır; bunu 3. Adım açıklar.

Nasıl test edildi: kod, gerçek bir DataDome sitesine karşı değil, benim yazdığım üç sahte (mock) sunucuya karşı çalıştırıldı. Birincisi CapSkip API belgeleri içindeki DataDome bölümünde listelenen denetimleri kopyalar; ikincisi 403 engelleme sayfası veren ve yalnızca CapSkip’in verdiği bir çerezi, verildiği User-Agent ile birlikte kabul eden korumalı bir sitenin, üçüncüsü ise bir forward proxy’nin yerini tutar. SDK, gerçek capskip 1.5.0 idi. Bilgisayarımda CapSkip uygulaması çalışmıyordu, bu yüzden buradaki hiçbir şey gerçek bir çözümün ne kadar sürdüğünü ya da canlı bir DataDome sitesinin neyi kabul ettiğini göstermez. Çerezle ilgili kurallar CapSkip belgelerinden gelir. DataDome’nin kendi çerez belgeleri datadome çerezinin bir yıl geçerli olduğunu söyler ve Domain ya da Path değerinin değiştirilmesine karşı uyarır. Çerezin neye bağlı olduğunu söylemez.

1. Adım: engelleme sayfasını okuyun ve captcha_url adresini oluşturun

DataDome bir isteğe şüpheyle yaklaştığında site, içerik yerine 403 durumuyla (bazen 401) ve küçük bir HTML sayfasıyla yanıt verir. Bu sayfa dd adlı bir script nesnesi barındırır ve challenge’ı geo.captcha-delivery.com üzerinden bir iframe içinde yükler. CapSkip’in ihtiyaç duyduğu şey iframe adresidir ve belgeler ona captcha_url der. Sayfada iframe zaten varsa src değerini olduğu gibi alabilirsiniz. Çoğu engelleme sayfası iframe’i bunun yerine bir script ile oluşturur; bu yüzden aşağıdaki fonksiyon aynı adresi dd nesnesinden derler.

rt değeri yolu belirler. c, /captcha/ altındaki kaydırıcı; i ise /interstitial/ altındaki cihaz kontrolü anlamına gelir. t değeri de önemlidir: fe bir challenge, bv ise sayfayı çeken IP adresini DataDome’nin yasakladığı anlamına gelir. İlk istek sade bir Chrome User-Agent ile gider. Bu dize CapSkip’e hiç gönderilmez, bu yüzden Chrome sürümünün hiçbir şeyle eşleşmesi gerekmez. Canlı bir DataDome sitesinin farklı bir User-Agent’a aynı challenge’ı verip vermediğini test etmedim, bu yüzden o kısmı denenmemiş sayın.

# 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)}"

Fonksiyon, yanıt bir engelleme sayfası değilse None döndürür; böylece bir script “çözülecek bir şey yok” ile “çözüldü” durumunu ayırt edebilir. Her engelleme sayfası yeni bir challenge getirir. Onun captcha_url değerini hemen kullanın ve sonraki görev için eski bir adresi yeniden kullanmak yerine sayfayı yeniden isteyin.

2. Adım: datadome() ile çözün

SDK metodu datadome(captcha_url, pageurl, userAgent, proxy) biçimindedir ve 2Captcha argüman sırasını izler. İlk ikisi zorunludur. CapSkip’te userAgent ve proxy isteğe bağlıdır. Bir User-Agent göndermezseniz CapSkip kendi tarayıcısınınkini kullanır ve sonuçta userAgent olarak döndürür. Gönderirseniz Windows için Chrome olmalı ve CapSkip’in tarayıcısıyla aynı ana sürüme sahip olmalıdır; bu yüzden onu hiç vermemek kolay seçimdir. CapSkip challenge’ı kendi çalıştırdığı gerçek bir tarayıcıda geçtiği için metot, reCAPTCHA’nın kullandığı daha uzun 300 saniyelik zaman aşımıyla bekler. API belgeleri bir çözümün genellikle 3 ila 20 saniye sürdüğünü söyler; ben bir tane ölçmedim.

Proxy, sonraki isteklerinizin kullanacağı proxy’dir. Script’iniz bir proxy üzerinden çıkıyorsa onu verin; istekler CapSkip’i çalıştıran makineden çıkıyorsa hiçbir şey vermeyin. CapSkip bir sunucuda çalışıyorsa o makine sunucudur.

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))

Cihaz kontrolü geçilemezse DataDome kaydırıcıya geçer. CapSkip belgelerine göre tek çağrı onu oraya kadar izler, bu yüzden iki challenge için ayrı kod yazmanız gerekmez.

3. Adım: çerezi User-Agent ve IP adresiyle birlikte gönderin

Sonuç, önemli olan dört alanı bulunan bir sözlüktür. code alanı, çerezin DataDome tarafından ayarlandığı hâliyle Max-Age, Domain ve diğer özniteliklerle birlikte tamamıdır; bir çerez deposunun istediği budur. cookie alanı yalnızca datadome ad ve değer çiftidir; bir Cookie başlığının istediği budur. userAgent alanı, onu kazanan User-Agent’tır. proxy alanı yalnızca siz proxy göndermediyseniz ve CapSkip kendi DataDome proxy listesi üzerinden çözdüyse görünür. CapSkip belgeleri, DataDome’nin çerezi başka bir IP adresinden ya da başka bir User-Agent ile reddettiğini söyler; bu yüzden her seferinde aynı User-Agent’ı gönderin ve sonuç bir proxy adlandırıyorsa isteği onun üzerinden gönderin. Bu proxy alanı yalnızca host ve porttur; şema ve giriş bilgisi yoktur. Fonksiyon http:// ekler ve bu yüzden girişi gerekmeyen bir liste proxy’si varsayar. Sizinkinde giriş varsa onu ekleyin.

DataDome sonraki bir yanıtta yerine geçen bir çerez de gönderebilir. Fonksiyon, bir tarayıcının yapacağı gibi en yenisini tutar.

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

Çerez başlıkta elle ayarlanır, bu yüzden requests onu sizin için yönetmez. Bu bilinçlidir: açık başlık oturum çerez deposunun önüne geçer ve çerezi, User-Agent’ı ve proxy’yi tek bir yerde bir arada tutar. Proxy çalıştırmasının gösterdiği bir şey: şemadan sonraki metin CapSkip’e yazdığınız gibi gider, bu yüzden proxy giriş bilgisini yüzde kodlaması gerektiren karakterlerden uzak tutun. Bir socks5 proxy için requests ayrıca socks ekstrasına ihtiyaç duyar; pip install requests[socks] ile kurulur.

4. Adım: tam çalışan örnek

Son blok, Python’da DataDome CAPTCHA çözme akışını bir araya getirir ve yeniden denemeyi ekler. Dört bloğun hepsini art arda tek bir dosyaya, datadome_demo.py adıyla kaydedin ve python datadome_demo.py ile çalıştırın. Her deneme sayfayı yeniden ister, bu yüzden her seferinde yeni bir challenge gelir. Başarısız bir çözüm ApiException fırlatır ve döngü yeniden dener. Buna rağmen 403 alan bir çerez de döngüyü yeni engelleme sayfasıyla başa döndürür.

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, t=bv içeren bir captcha_url adresini hiçbir şey göndermeden önce reddeder, çünkü o adresten yapılan hiçbir çözüm geçemez. Bu ValidationException bir ApiException değildir, bu yüzden döngü onu yakalamaz. Görünür kalmasına izin verin: adresi değiştirip baştan başlamanın işaretidir. CapSkip’in bunun yerine ERROR_PROXY_BANNED olarak bildirdiği bir yasak ise ApiException olarak gelir ve döngü onu aynı adreste yeniden dener; bu yüzden çıktıda bu hatayı görürseniz yeniden çalıştırmadan önce proxy’yi değiştirin. Proxy döndürme kılavuzu proxy’lerin nasıl döndürüleceğini anlatır; CAPTCHA’yı engelden ayırt etme sayfanın hiç de bir challenge olmadığı diğer durumu ele alır.

Mock çalıştırmasında script şöyle davrandı:

Mock ayarıScript ne yaptı
Kaydırıcı engelleme sayfası, her çözüm yanıtlandıBir görev, ardından çerezle 200 durumu ve yeniden kullanımda yine 200
Cihaz kontrolü engelleme sayfasıAynı kod çalıştı: captcha_url /interstitial/ adresini gösterdi ve sonuç aynıydı
İlk iki çözüm reddedildiİki deneme satırı, ardından üçüncü görevde 200 durumu
İlk üç çözüm reddedildiÜç deneme satırı, ardından RuntimeError
Sonuç, CapSkip’in kendi listesinin yaptığı gibi bir proxy adlandırıyorÇerez isteği o proxy üzerinden gitti ve 200 aldı
Çözüme kendi proxy’niz verildiin.php proxy’yi ve türünü aldı, istekler de onu kullandı
t=bv içeren engelleme sayfasıValidationException, mock CapSkip hiç istek görmedi
Farklı bir User-Agent ile gönderilen çerezMock site 403 yanıtı verdi
Farklı bir IP adresinden gönderilen çerezCapSkip’in bir proxy üzerinden verdiği çerez proxy olmadan gönderilince mock site 403 yanıtı verdi

Son iki satır, CapSkip belgelerini izleyen mock’umun kurallarını sınar. Gerçek hizmet hakkında kanıt değildir.

Yaygın hatalar

HataNedenDüzeltme
ValidationExceptionDataDome challenge adresi olmayan bir captcha_url, t=bv içeren bir engelleme sayfası, http ya da https olmayan bir pageurl veya Windows için Chrome olmayan bir userAgent. İleti bunlardan hangisi olduğunu söylerAdresi yeni bir engelleme sayfasından yeniden oluşturun, yasaklıysa adresi değiştirin ve userAgent argümanını kaldırın
ApiException ile ERROR_WRONG_USERAGENTUser-Agent Windows için Chrome ama ana sürümü CapSkip’in tarayıcısından farklıuserAgent göndermeyin ve sonucun bildirdiğini kullanın
ERROR_CAPTCHA_UNSOLVABLE içeren ApiExceptionChallenge geçilemediSayfayı yeniden isteyin ve yeni captcha_url değerini gönderin
ApiException ile ERROR_PROXY_BANNEDCapSkip, API belgelerine göre engelleme sayfası t=bv diyen bir görevi reddederProxy’yi değiştirin ve sayfayı yeniden isteyin
ApiException ile ERROR_PROXY_CONNECT_REFUSEDCapSkip, proxy üzerinden bağlanamadığında bunu bildirir. Yeniden üretmedimProxy adresini, giriş bilgisini ve türünü kontrol edin
TimeoutExceptionCapSkip 300 saniyelik bekleme içinde yanıt vermedi. Bu bir ApiException değildir, bu yüzden döngü onu yakalamazCapSkip’in çalıştığını ve çözdüğünü kontrol edin, sonra script’i yeniden çalıştırın
NetworkExceptionCapSkip çalışmıyor ya da host veya port yanlışCapSkip’i başlatın ve bağlantı ayarlarını kontrol edin
Çerezle birlikte hâlâ 403İstek başka bir IP adresinden çıktı, başka bir User-Agent kullandı ya da çerezin süresi dolduSonucun userAgent ve proxy değerlerini her seferinde gönderin ya da döngüyü yeni engelleme sayfasıyla yeniden çalıştırın

Çözücüyü bir sunucuda çalıştırmak

Script’in CapSkip’ten iki şeye ihtiyacı var: bir host ve bir port. Local modunda bunlar 127.0.0.1 ve kendi bilgisayarınızdır. Server modunda CapSkip ağ adresinizi veya genel bir IP’yi dinler, böylece başka bir bilgisayardaki, bir VPS’teki veya barındırılan bir platformdaki script aynı API üzerinden ona erişebilir. Host ve port değerlerini CapSkip constructor’ında değiştirin; başka hiçbir şey değişmez. Kararlı uzaktan erişim için statik bir genel IP önerilir. Server modu da kendi donanımınızda çalışır ve çözüm başına ücretlendirme yoktur. Yine de portu her adrese açar, bu yüzden ulaşmaması gereken adresler için bir Windows Firewall engelleme kuralı ekleyin. Çözümün o makinede çalıştığını unutmayın; bu yüzden çerez sunucunun IP adresinden kazanılır. Bir proxy vermezseniz çerezi taşıyan istek de o sunucudan çıkmak zorundadır. Bir proxy kullanıyorsanız aynısını hem çözüme hem isteklerinize verin. Modlar arasında nasıl geçileceğini bağlantı ayarları bölümünde bulabilirsiniz.

FAQ

DataDome çözücü bir token döndürür mü?

Hayır. datadome çerezini döndürür. Bu çerezi, engellenen isteğin Cookie başlığında, aynı User-Agent ile birlikte gönderirsiniz. Doldurulacak bir form alanı yoktur.

DataDome için proxy gerekir mi?

Test için gerekmez. İlk çalıştırma için tek bir IP adresi yeterlidir. CapSkip belgelerine göre çerez yalnızca onu kazanan IP adresinden çalışır; bu yüzden çok sayıda istek göndermeye başladığınızda görev başına bir sticky proxy planlayın ve aynı proxy’yi hem çözüme hem isteklerinize verin.

Bu hem kaydırıcı hem cihaz kontrolü için çalışır mı?

Evet, aynı çağrıyla. Kaydırıcının captcha_url değeri /captcha/ altında, cihaz kontrolününki /interstitial/ altındadır. CapSkip belgeleri, kaydırıcıya yükselen bir cihaz kontrolünün oraya kadar izlendiğini söyler.

Barındırılan bir platform bunu benim CapSkip’ime karşı çalıştırabilir mi?

Evet, Server modu ile. CapSkip’i ağınızı veya genel IP’nizi dinleyecek şekilde ayarlayın, CapSkip constructor’ını o host ve port bilgisine yöneltin; döngü aynı çalışır, tek bir farkla: çözüm artık sunucuda çalışır, bu yüzden çözüme ve isteklerinize aynı proxy’yi verin. Çözücü sizin donanımınızda kalır.

Kısa özet

Python’da bir DataDome CAPTCHA’sını çözmek dört hamle sürer: engelleme sayfasını okuyun, captcha_url adresini oluşturun, datadome() metodunu çağırın ve isteği çerezle, User-Agent ile ve ait olduğu IP adresiyle yineleyin. Kendi makinenizde yeniden denemek ücretsizdir. Bir yerel captcha çözücü ile korumalı bir site size sürekli yeni challenge vermeye devam etse bile her yeniden deneme ücretsizdir. SDK’nın geri kalanı için bkz. Python CAPTCHA çözücü sayfası.