Python’da hCaptcha Çözme: CapSkip SDK ile Tek Çağrı, Tek Token

Python’da hCaptcha’yı CapSkip SDK ile çözmek için solver.hcaptcha() fonksiyonunu widget’ın sitekey’i ve sayfa adresiyle çağırın, sonra formunuzu dönen token ve bildirdiği User-Agent ile gönderin. SDK görevi gönderir, sonucu yoklar ve iki değeri de geri verir; bu yüzden script’in büyük kısmı yeniden deneme kuralları ve form gönderimidir. Arkadaki çözücü: CapSkip hCaptcha çözücüsü. Kendi Windows bilgisayarınızda sabit bir lisansla çalışır; bu yüzden süresi dolan ya da reddedilen bir token’ı yenilemek hiçbir şeye mal olmaz.
Neye ihtiyacınız var
- CapSkip 4.0.0 veya üzerini çalıştıran bir Windows bilgisayarı. Bu sürüm, 3 Kasım 2026 tarihinde Enterprise dahil hCaptcha çözme desteğini ekledi. Kurulum için bkz. kurulum kılavuzu.
- Python 3.10 veya üzeri (capskip paketinin bildirdiği asgari sürüm) ve iki paket: hCaptcha metodu bulunan ilk sürüm olan capskip 1.6.0 veya üzeri ile requests. capskip 1.6.0 ve requests 2.34.2 ile Python 3.11.7 ve 3.14.0 üzerinde denendi, başka sürümlerde denenmedi.
- Bir PowerShell istemi; pip install capskip requests komutunu burada çalıştırırsınız.
- Sahibi olduğunuz ya da otomatikleştirmenize izin verilen, hCaptcha widget’ı bulunan bir sayfa ve onun sitekey’i. Sitekey’i nerede bulacağınızı 2. Adım gösterir.
- CapSkip için bir adres. Modu, script’in nerede çalıştığı belirler. Local modu (127.0.0.1) yalnızca CapSkip’in bulunduğu bilgisayara hizmet verir. Server modu ayrıca ağınızı veya genel IP’nizi dinler, böylece başka bir bilgisayar, bir Windows VPS veya barındırılan bir platform aynı istekleri gönderebilir. Modlar arasındaki geçişi şuradan yaparsınız: bağlantı ayarları. Aşağıdaki kod varsayılan CapSkip biçimini bekler, bu yüzden Service Emulator ayarını varsayılan değerinde bırakın.
- İsteğe bağlı: bir proxy. Nereye gireceğini 2. Adım anlatır.
Nasıl test edildi: benim yazdığım iki sahte (mock) sunucuya karşı; gerçek CapSkip uygulamasına ya da canlı bir hCaptcha sitesine karşı değil. Birincisi CapSkip API belgeleriiçindeki hCaptcha bölümünde listelenen denetimleri kopyalar. İkincisi bir kayıt formunun yerini tutar ve aynı zamanda forward proxy olarak çalışır. Buradaki hiçbir şey gerçek bir çözüm süresini ölçmez; mock’taki site kuralları (tek kullanımlık token, eşleşen User-Agent, iki dakikalık geçerlilik) hCaptcha’dan değil, CapSkip belgelerinden gelir. Gerçek denetimi hedeflediğiniz site yapar. Bunun nasıl işlediğine dair ayrıntılar hCaptcha geliştirici belgelerinde.
1. Adım: solver’ı oluşturun
Aşağıdaki dört kod bloğu sırayla tek bir dosyaya girer. Dosyanın adı hcaptcha_demo.py olsun. Son blok yerine oturana kadar hiçbir şey çalışmaz. Bu çalıştırmalardaki SDK gerçek capskip 1.6.0 idi; yalnızca arkasındaki CapSkip uygulaması bir mock’tu. Constructor’ın apiKey argümanı varsayılan olarak capskip dizesini alır; bu, API Key Validation kapalıyken çalışır. Doğrulamayı açtıysanız anahtarınızı apiKey olarak verin.
Constructor ayrıca SDK’nın hCaptcha için ne kadar bekleyeceğini belirler. Varsayılanı 300 saniye olan recaptchaTimeout argümanı geçerlidir, çünkü widget gerçek bir tarayıcıda geçilir. Kod bunu 180 saniyeye düşürür; bu benim seçimim, bir CapSkip ayarı değil. Bu sınır yalnızca yoklamayı kapsar. SDK kendi HTTP çağrılarına zaman aşımı koymaz; mock’a karşı 20 saniye geciktirilen bir yanıt, recaptchaTimeout 5 iken çağrıyı tam 20 saniye bekletti. Sorunlar, capskip’ten içe aktardığınız istisnalar olarak gelir: SDK argümanlarınızı hiçbir şey göndermeden reddettiğinde ValidationException, CapSkip bir hata kodu verdiğinde ApiException, bekleme bittiğinde TimeoutException ve CapSkip’e ulaşılamadığında NetworkException.
# pip install capskip requests import re import requests from capskip import ApiException, CapSkip PAGE_URL = "https://example.com/signup" # the page that shows the widget SITEKEY = "YOUR_SITEKEY" # the data-sitekey of its h-captcha div # Local mode. In Server mode, use your server's address as the host. # With API Key Validation on, also pass apiKey="YOUR_API_KEY". solver = CapSkip(host="127.0.0.1", port=8080, recaptchaTimeout=180)
2. Adım: CapSkip’ten token’ı isteyin
Sitekey herkese açıktır ve her ziyaretçi için aynıdır. Çoğu sayfa onu widget kapsayıcısında data-sitekey olarak yazdırır. Widget’ı bir script ile oluşturan bir sayfa onu hcaptcha.render() çağrısının sitekey seçeneği olarak verir ve hCaptcha iframe adresi onu sitekey= olarak taşır. Onu SITEKEY içine, widget’ı gösteren sayfanın tam adresini de PAGE_URL içine koyun.
Çağrı solver.hcaptcha(SITEKEY, PAGE_URL) biçimindedir. Görevi gönderir ve token hazır olana kadar yoklar, bu yüzden bir görev ID’si tutmazsınız ve döngü yazmazsınız. Ham API belgeleri önce 10 saniye beklemenizi önerir, ama SDK hemen yoklar, sonra 0,25 saniye uyur ve hazır değil yanıtı geldikçe bunu her seferinde ikiye katlayarak en çok 5 saniyeye çıkarır. Belgelere göre bir çözüm kural olarak 10 ile 30 saniye sürer. Gerçek birini hiç ölçmedim.
Sonuç bir sözlüktür. token ve code alanları aynı dizeyi taşır; bu, h-captcha-response için olan değerdir. userAgent ise onu kazanan User-Agent’tır. respKey alanı, hCaptcha’nın widget’a verdiği ikinci bir değerdir. Her zaman bulunur, yoksa boştur; belgeler çoğu sitenin onu hiç okumadığını söyler, bu yüzden kod onu yok sayar. Her sonuç bir kez teslim edilir ve SDK onu sizin için okur, böylece fonksiyon token’ı ve User-Agent’ı birlikte geri verir. Belgeler, CapSkip’in userAgent argümanını yalnızca kendi çözdüğü tarayıcıyla eşleştiğinde kullandığını söyler; bu yüzden örnek seçimi CapSkip’e bırakır.
Bu yöntem için proxy isteğe bağlıdır. Belgeler, test için tek bir adresin yeterli olduğunu ve tek bir IP’den gelen düzenli çözüm akışının, hCaptcha’nın hız sınırlarının tam da yakalamak için kurulduğu şey olduğunu söyler. Yüksek hacim için hCaptcha ayarlarında bir proxy listesi yükleyin ya da her görevle bir proxy gönderin. Görevdeki proxy listeye üstün gelir. Fonksiyon bir proxy’yi http://user:[email protected]:8080 gibi tam bir URL olarak alır, şemayı proxytype olarak, kalanını proxy alanı olarak gönderir. HTTP ve HTTPS proxy’ler olduğu gibi çalışır. Bir SOCKS proxy için önce pip install requests[socks] çalıştırın. Proxy’leri döndürüyorsanız, Proxy döndürme kılavuzu bunun nasıl yapıldığını gösterir.
def solve(proxy=None):
options = {}
if proxy: # for example http://user:[email protected]:8080
scheme, address = proxy.split("://", 1)
# The SDK sends type as proxytype and uri as proxy.
options["proxy"] = {"type": scheme.upper(), "uri": address}
result = solver.hcaptcha(SITEKEY, PAGE_URL, **options)
return result["token"], result["userAgent"] # delivered once: keep both3. Adım: formu aynı User-Agent ile gönderin
Bir tarayıcıda widget, token’ı h-captcha-response adlı gizli bir textarea alanına yazar; g-recaptcha-response adlı bir kopyası da vardır. Tarayıcı olmadan h-captcha-response alanını kendiniz gönderirsiniz, form bir g-recaptcha-response alanı içeriyorsa onu da. Aşağıdaki kod ikisini de gönderir. Formunuzun kendi alanları bunlarla birlikte gelir ve adları sitenin kullandığı adlardır. Gönderim PAGE_URL adresine gider; bu yüzden formun action değeri başka bir adrese işaret ediyorsa, post çağrısının ilk argümanını, yani PAGE_URL değerini değiştirin.
User-Agent önemlidir. Yanıt, token’ı kazanan tarayıcıyı adlandırır ve belgeler formu aynı dizeyle göndermenizi ister. Bu yüzden fonksiyon onu sayfa yüklenmeden önce oturuma ayarlar; sayfa yüklemesi ve gönderim aynı User-Agent’ı taşır. Token’lar tek kullanımlıktır ve verildikten yaklaşık iki dakika sonra sona erer, bu yüzden hemen gönderin ve her denemede yeni bir tane isteyin.
Gönderim ayrıca geldiği sayfayı Referer olarak bildirir, çünkü requests kendiliğinden ne Referer ne de Origin başlığı gönderir. Bazı framework’ler bu ikisinden de yoksun bir HTTPS form gönderimini reddeder. Örneğin Django CSRF belgeleri, Origin başlığı olmadan gelen HTTPS istekleri için sıkı bir referer denetimini tarif eder.
def submit_form(session, token, user_agent, email):
# Every request from here on carries the User-Agent the token was
# earned with, the page load included.
session.headers["User-Agent"] = user_agent
session.get(PAGE_URL, timeout=30) # picks up the page's own cookies
return session.post(
PAGE_URL,
data={
"email": email, # your form's own fields go here
"h-captcha-response": token,
"g-recaptcha-response": token, # the widget fills both
},
headers={"Referer": PAGE_URL}, # requests sends no Referer by itself
timeout=30,
)4. Adım: yeniden deneme kurallarıyla tam örnek
Son blok adımları tek bir script’te birleştirir. Onu hcaptcha_demo.py dosyasının sonuna ekleyin, en üstteki PAGE_URL ve SITEKEY değerlerinin sizin olduğunu kontrol edin ve dosyanın bulunduğu klasörden python hcaptcha_demo.py komutunu çalıştırın (python PATH içinde değilse py hcaptcha_demo.py çalışır). Script en fazla üç deneme yapar.
Hangi hatanın yeniden deneneceğini hata kodu belirler. Belgeler, ERROR_CAPTCHA_UNSOLVABLE kodunun görevin başarısız olduğu anlamına geldiğini ve yeni bir görev gönderilmesi gerektiğini söyler; bu yüzden yeniden deneme kümesindeki tek kod odur. İki başka hata nedenini adıyla belirtir, çünkü yeniden gönderme aynı şekilde başarısız olurdu: hCaptcha’nın sayfa için reddettiği bir sitekey ve ulaşılamayan bir proxy. Yaygın hatalar tablosundaki diğer kodlar isteğe ya da kuruluma işaret eder. SDK kodu ApiException iletisinin içine, düz metin olarak ya da küçük bir JSON zarfı içinde koyar; bu yüzden error_code, ERROR_ sözcüğünü ayıklar ve ikisiyle de çalışır. Geri kalan her şey script’i hemen durdurur; buna döngünün yakalamadığı üç istisna da dahildir: ValidationException, TimeoutException ve NetworkException.
Sitenin reddettiği bir form yeni bir token ve bir deneme daha alır. Üç token da aynı şekilde başarısız olursa form alanlarına bakın. Eksik bir alan için HTTP 400, token ne kadar iyi olursa olsun tekrarlanır. Ayrıca reply.ok yalnızca durumun 400 değerinin altında olduğu anlamına gelir. Birçok site 200 yanıtı verir ve sayfada bir hata iletisi gösterir; bu yüzden o testi, sitenizin yalnızca başarıda gösterdiği bir şeyin kontrolüyle değiştirin.
# Only a task CapSkip could not solve gets another try. A bad sitekey, a
# dead proxy or a wrong key would fail the same way again.
RETRY = {"ERROR_CAPTCHA_UNSOLVABLE"}
def error_code(err):
# The message holds the code as bare text or inside a JSON envelope.
found = re.search(r"ERROR_[A-Z_]+", str(err))
return found.group(0) if found else str(err)
def sign_up(email, proxy=None):
session = requests.Session()
if proxy:
session.proxies = {"http": proxy, "https": proxy}
for attempt in range(1, 4):
try:
token, user_agent = solve(proxy)
except ApiException as err:
code = error_code(err)
if code not in RETRY:
raise
print(f"attempt {attempt}: {code}, new task")
continue
reply = submit_form(session, token, user_agent, email)
if reply.ok:
return reply
print(f"attempt {attempt}: the site answered {reply.status_code}, new token")
raise RuntimeError("no accepted form after 3 attempts")
if __name__ == "__main__":
reply = sign_up("[email protected]")
print(reply.status_code, reply.text[:60])Mock çalıştırmasında script şöyle davrandı; sonuçlar Python 3.11.7 ve 3.14.0 üzerinde aynıydı:
| Mock ayarı | Script ne yaptı |
|---|---|
| Token ikinci sorguda hazırdı | Bir görev, ardından form 200 durumuyla kabul edildi |
| İlk iki çözüm reddedildi | İki deneme satırı, ardından üçüncü görevde 200 durumu |
| Site ilk form gönderimine 403 yanıtı veriyor | Bir deneme satırı, yeni bir token ile ikinci bir görev, ardından 200 durumu |
| Sorguda ERROR_PROXY_CONNECT_REFUSED | Bir görevden sonra fırlatıldı, yeniden deneme olmadı |
| Hatalar JSON yerine düz metin olarak gönderiliyor | JSON ile aynı davranış, yeniden deneme dahil |
| sign_up fonksiyonuna verilen bir proxy URL’si | in.php proxy’yi proxytype HTTP ile aldı; sayfa yüklemesi ve form gönderimi, ikisi de proxy mock’undan geçti |
| Varsayılan requests User-Agent’ı ile gönderilen token | Mock site 403 yanıtı verdi |
| Aynı token iki kez gönderildi | İkinci gönderim 403 aldı |
| CapSkip hiç hazır olmuyor, recaptchaTimeout 25 saniyeye düşürüldü | Çağrıdan yaklaşık 28 saniye sonra TimeoutException, çünkü yoklamalar arasındaki son uyku 5 saniyedir |
Site satırlarını kendi mock’umun testleri olarak değerlendirin. Kuralları CapSkip belgelerini izler; yalnızca bir oturum çerezi denetimi ve iki token alanının da eşleşmesi şartını ben ekledim. Bunlar hCaptcha hakkında ya da gerçek bir site hakkında hiçbir şeyi kanıtlamaz.
Yaygın hatalar
| Hata | Neden | Düzeltme |
|---|---|---|
| ValidationException | SDK çağrıyı göndermeden reddetti: boş bir sitekey, tam bir http veya https URL’si olmayan bir sayfa adresi, 0, 1, true veya false dışında bir invisible değeri, desteklenmeyen bir proxy türü ya da CapSkip hCaptcha API’sinin almadığı bir seçenek, örneğin 2Captcha’nın domain seçeneği | İletiyi okuyun, sorunu adıyla söyler; sonra argümanı düzeltin |
| ERROR_RECAPTCHA_INVALID_SITEKEY | hCaptcha sitekey’i o sayfa için reddetti. Boş bir sitekey buraya hiç gelmez, çünkü SDK onu önce reddeder | data-sitekey değerini sayfadan yeniden kopyalayın ve PAGE_URL adresinin widget’ı gösteren sayfa olduğunu kontrol edin |
| ERROR_CAPTCHA_UNSOLVABLE | hCaptcha geçilemedi | Yeni bir görev gönderin. Döngü bunu üç kereye kadar yapar |
| ERROR_PROXY_FORMAT | CapSkip proxy değerini okuyamadı | Proxy değerini kontrol edin. CapSkip IP:PORT, LOGIN:PASSWORD@IP:PORT ve IP:PORT:LOGIN:PASSWORD biçimlerini okur; bu script http://user:pass@IP:PORT gibi bir URL’yi bir proxytype değerine ve şemadan sonraki adrese böler |
| ERROR_PROXY_CONNECT_REFUSED | Hedefe proxy üzerinden ulaşılamadı. Bunu yalnızca benzetebildim | Proxy’yi tek başına test edin, sonra türünü ve giriş bilgisini yeniden kontrol edin |
| ERROR_TASK_NOT_SUPPORTED | Bu CapSkip görev türünü kabul etmiyor. Olası nedenler: 4.0.0 öncesi bir sürüm ya da hCaptcha’yı reddeden bir servise ayarlanmış Service Emulator | CapSkip’i 4.0.0 veya üzerine güncelleyin ve Service Emulator ayarını varsayılanda bırakın |
| ERROR_WRONG_USER_KEY veya ERROR_KEY_DOES_NOT_EXIST | API Key Validation açıkken anahtar yanlış. apiKey vermezseniz SDK capskip dizesini gönderir | Anahtarınızı CapSkip() fonksiyonunun apiKey argümanı olarak verin |
| TimeoutException | 1. Adım’da recaptchaTimeout ile belirlenen 180 saniyelik beklemeden sonra token gelmedi ya da SDK yoklarken CapSkip yanıt vermeyi bıraktı; SDK bunu hazır değil sayar. Yeniden deneme kümesinde değil | CapSkip’i açın, görev için Monitor sekmesine bakın, sonra script’i yeniden çalıştırın |
| NetworkException | CapSkip() fonksiyonuna verdiğiniz host ve portta hiçbir şey dinlemiyor ya da CapSkip bir HTTP hata durumuyla yanıt verdi | CapSkip’i başlatın, sonra host ve portu bağlantı ayarlarıyla karşılaştırın |
| Site geçerli görünen bir token’ı reddediyor | Token daha önce kullanılmıştı, yaklaşık iki dakikadan eskiydi, başka bir User-Agent ile geldi ya da gönderimde Referer yoktu. İlk üç neden CapSkip belgelerinden gelir | Her token’ı bir kez, hemen, aynı yanıttaki User-Agent ile ve sayfa Referer olarak gönderin |
Site token’ı hâlâ reddediyorsa
Bazı siteler, özellikle hCaptcha Enterprise kullananlar, widget geçilmiş olsa bile hCaptcha’nın riskli olarak puanladığı token’ları reddeder. CapSkip belgeleri bunlara katı sitekey’ler der. Belgeler hCaptcha için High score mode önerir; ayar Settings, Captcha types, hCaptcha altındadır. CapSkip’i çalıştıran bilgisayarda Google Chrome kurulu olmalıdır. 4.0.0 değişiklik günlüğü, modun varsayılan olarak açık olduğunu ve kapalıyken ya da Chrome yokken hCaptcha’nın CapSkip Custom Browser içinde çözüldüğünü söyler. Belgeler ayrıca iyi bir proxy ister ve formun aynı adresten, yanıttaki User-Agent ile gönderilmesini ister. Gerçek bir katı site olmadan bunların hiçbirini test edemedim; bu yüzden bunu benim doğruladığım bir şey değil, CapSkip belgelerinin yönlendirmesi olarak değerlendirin.
Script’inizden bir sunucudaki CapSkip’i kullanmak
Script’in CapSkip’ten ihtiyaç duyduğu tek şey bir host ve bir port. Server modunda CapSkip, ağınızdaki diğer cihazlardan ya da bir Windows VPS üzerinden internetten gelen bağlantıları da kabul eder ve kurulum kılavuzu kararlı erişim için statik bir genel IP önerir. Server modu CapSkip’in yönetici olarak çalışmasını gerektirir. Sunucunun adresini ve portunu CapSkip() çağrısına verin, script’te başka hiçbir şey değişmez. Sahiplik ve faturalandırma da değişmez: makine sizindir ve hiçbir şey ölçülmez. Ancak bu, portu diğer adreslere açık bırakır; bu yüzden güvenmediğiniz her adres için bir Windows Firewall engelleme kuralı oluşturun.
Çözüm artık sunucuda gerçekleşir. Katı bir sitekey için belgeler iki tarafta da aynı adresi ister; bu yüzden sign_up fonksiyonunun proxy argümanına bir proxy verin, hem göreve hem oturumunuza gitsin.
FAQ
Async istemciyi kullanabilir miyim?
Evet. AsyncCapSkip aynı constructor argümanlarını alır ve hcaptcha() metodunu aynı sitekey ve sayfa adresiyle await etmek aynı sözlüğü döndürür. pip’in capskip ile birlikte kurduğu httpx kullanır. Yalnızca mock’a karşı çalıştırdım.
CapSkip’i barındırılan bir platformdan çağırabilir miyim?
Evet, Server modu üzerinden. CapSkip’i ulaşılabilir bir adresi olan bir Windows makinesinde çalıştırın, o adresi CapSkip() çağrısına verin; çağrılar aynı kalır. Çözücü sizin denetlediğiniz donanımda kalır, platform ona yalnızca HTTP istekleri gönderir.
Peki invisible ve Enterprise widget’lar?
Aynı hcaptcha() metodunu kullanırlar. Invisible bir widget’ta data-size özniteliği invisible olarak ayarlıdır, bu yüzden invisible=True verin. Bir rqdata değeri ayarlayan Enterprise bir site için onu data olarak verin ve her görev için yenisini alın. Mock’a karşı, her iki durumda da in.php, invisible=1 ve data değerini aldı. İkisini de gerçek bir sitede çalıştırmadım.
Kısa özet
Python’da hCaptcha çözmek, tek bir hcaptcha() çağrısına ve token’ı kazanan User-Agent altında yapılan bir form gönderimine iner. Yalnızca CapSkip görevi çözemediğinde yeniden deneyin ve diğer her hatanın script’i durdurmasına izin verin. CapSkip bir yerel captcha çözücü olduğu için reddedilen bir token’ı yeniden denemek, döngüyü bir kez daha çalıştırmaktan ibarettir. Python CAPTCHA çözücü sayfası diğer türler için SDK çağrılarını içerir. Widget’ın geçtiğini görmek için bkz. hCaptcha demosu.
