Python'da data-s Parametresiyle reCAPTCHA Nasıl Çözülür

Google'ın kendi sayfaları reCAPTCHA widget'ında fazladan bir değer gönderir ve bunun adı data-s. Bunlardan birini olağan yolla çözerseniz, sayfanın ardından reddettiği bir token alırsınız. Çözüm tek bir argüman daha: data-s değerini sayfa HTML'inden okuyun, çözücüye iletin ve token'ı hemen gönderin.
recaptcha data-s parametresi, neredeyse herkesin gözden kaçırdığı parçadır; bunun başlıca nedeni de normal sitelerde bulunmamasıdır. İşte nerede durduğu, kodda ne ad verileceği ve baştan sona çalışan bir betik.
data-s aslında nedir
Google'ın kendi mülklerindeki reCAPTCHA widget'larına eklediği, kısa ömürlü ve tek kullanımlık bir değerdir. En sık karşılaşacağınız örnek, Google Arama'daki “olağan dışı trafik” ara sayfasıdır. Bu değer, challenge'ı o belirli sayfa yüklemesine bağlar; dolayısıyla geri aldığınız token yalnızca aynı istek bağlamında geçerlidir.
Bundan üç sonuç çıkar ve üçü de hatalara yol açar:
- Süresi dolar. Ona bir nonce gibi davranın. Sayfayı çekin, çözün, gönderin. Çalıştırmalar arasında önbelleğe almayın.
- Yalnızca Google'a özgüdür. Başkasının sitesindeki bir reCAPTCHA'da şu bulunmaz:
data-s. Yine de göndermek zararsız bir fazlalık değil, bir parametre hatasıdır. - Enterprise bayrağıyla aynı şey değildir. Bu ikisi sürekli birbirine karıştırılır.
data-sveenterprisefarklı sorunları çözen ayrı seçeneklerdir ve reCAPTCHA Enterprise çözücü sayfası ikincisini ele alır.
Neye ihtiyacınız var
- CapSkip yerel olarak çalışıyor olmalı. Varsayılan olarak dinlediği adres
127.0.0.1:8080şeklindedir ve kurulum kılavuzu sayfası kurulumu anlatır. - Python 3.10 veya daha yenisi.
- SDK ve bir HTTP istemcisi.
# the CapSkip SDK plus requests for fetching the page pip install capskip requests
data-s değeri nerede bulunur
İhtiyacınız olan iki değer de aynı elemanda yer alır. Widget şu elemanla render edilir: div şunları taşır: data-sitekey ve yalnızca Google'ın sayfalarında, data-s:
<div class="g-recaptcha"
data-sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
data-s="SGVsbG8gdGhlcmUsIHRoaXMgaXMgYSBvbmUtdGltZSB2YWx1ZQ">
</div>Site anahtarı (sitekey) sabittir ve kodun içine gömebilirsiniz. data-s değeri her yüklemede değişir, bu yüzden çalışma zamanında kazınması gerekir:
# pip install capskip requests import re import requests PAGE = "https://www.google.com/search?q=example" # Keep one session. The value is tied to the request that # produced it, cookies included. session = requests.Session() html = session.get(PAGE, timeout=30).text sitekey = re.search(r'data-sitekey="([^"]+)"', html).group(1) datas = re.search(r'data-s="([^"]+)"', html).group(1) print(sitekey, datas) # second value is single use
İkinci eşleşme boş dönerse, bir Google sayfasında değilsinizdir ve bu parametreye hiç ihtiyacınız yoktur. Bunun yerine sıradan bir v2 challenge'ı gibi çözün.
datas olarak iletin, data-s olarak değil
Adlandırma tuzağı burada. Ham HTTP API, parametreyi HTML'de göründüğü haliyle alır, data-s. SDK'lar bu adı kullanamaz, çünkü Python'da bir anahtar sözcük argümanında tire geçerli değildir; bu yüzden her SDK bunu şu adla sunar: datas.
| Nerede | Ad |
|---|---|
| Sayfa HTML'i | data-s |
Şuradaki ham API: in.php | data-s |
| Python, Node.js, PHP, .NET SDK'ları | datas |
Bu hallolduğunda çözüm tek bir çağrıdan ibaret:
from capskip import CapSkip
solver = CapSkip(host="127.0.0.1", port=8080)
result = solver.recaptcha(
sitekey=sitekey,
url=PAGE,
datas=datas, # the data-s value, scraped seconds ago
)
print(result["code"]) # g-recaptcha-response tokenTam çalışan örnek
Çekin, kazıyın, çözün, gönderin; hepsi tek bir session üzerinde olsun ki çerezler ve IP tutarlı kalsın:
# pip install capskip requests
import re
import requests
from capskip import (
CapSkip, ApiException, NetworkException, TimeoutException,
)
PAGE = "https://www.google.com/search?q=example"
session = requests.Session()
solver = CapSkip(host="127.0.0.1", port=8080, recaptchaTimeout=300)
html = session.get(PAGE, timeout=30).text
sitekey = re.search(r'data-sitekey="([^"]+)"', html).group(1)
datas = re.search(r'data-s="([^"]+)"', html).group(1)
try:
result = solver.recaptcha(sitekey=sitekey, url=PAGE, datas=datas)
except NetworkException:
raise SystemExit("CapSkip is not running on 127.0.0.1:8080")
except TimeoutException:
raise SystemExit("solve took longer than recaptchaTimeout")
except ApiException as err:
raise SystemExit(f"API refused the task: {err}")
# Submit immediately. The token is good for about two minutes.
response = session.post(
PAGE,
data={"g-recaptcha-response": result["code"]},
timeout=30,
)
print(response.status_code)Buradaki iki ayrıntı göründüğünden daha önemli. session yeniden kullanılır, böylece çözüm ile gönderim aynı çerezleri paylaşır. Gönderim de çözümün hemen ardından gerçekleşir; çünkü bir reCAPTCHA token'ı verilmesinden yaklaşık iki dakika sonra kabul edilmemeye başlar.
Proxy arkasında
Sayfayı bir proxy üzerinden çektiyseniz, çözümü de aynısı üzerinden yapın. Challenge, kendisini oluşturan isteğe bağlıdır ve farklı bir ağ yolundan yapılan bir çözüm, reddedilen token'ların ikinci en yaygın nedenidir.
result = solver.recaptcha(
sitekey=sitekey,
url=PAGE,
datas=datas,
proxy={"type": "HTTPS", "uri": "user:[email protected]:3128"},
)Proxy'ler reCAPTCHA, Turnstile ve GeeTest için işe yarar. Hedef siteye hiç dokunmayan görsel CAPTCHA'lar için ise hiçbir şey yapmaz.
SDK olmadan aynı çağrı
API 2captcha uyumludur ve sizin makinenizde çalışır, dolayısıyla herhangi bir HTTP istemcisi iş görür. Burada parametre tiresini korur:
# submit the task, get an ID back
curl -s -X POST "http://127.0.0.1:8080/in.php" \
-d "key=capskip" \
-d "method=userrecaptcha" \
-d "googlekey=YOUR_SITEKEY" \
-d "pageurl=https://www.google.com/search?q=example" \
-d "data-s=THE_DATA_S_VALUE" \
-d "json=1"
# {"status":1,"request":"2122988149"}Ardından şunu yoklayın: res.php token için. Yoklama gecikmeleri dahil olmak üzere iki çağrılık akışın tamamı şurada: cURL ile CAPTCHA çözme.
Diğer SDK'lar da aynı datas yazımını kullanır. Node.js bunu seçenekler nesnesinde alır, .NET ise seçenekler sözlüğüne koyar:
// npm install capskip
const { CapSkip } = require('capskip');
const solver = new CapSkip({ host: '127.0.0.1', port: 8080 });
const result = await solver.recaptcha(sitekey, pageUrl, {
datas: dataS, // same value, same rules
});
console.log(result.code);Yaygın hatalar
| Gördüğünüz | Neden | Düzeltme |
|---|---|---|
ERROR_GOOGLEKEY | Sitekey isteğe hiç ulaşmadı ya da regex yanlış özniteliği yakaladı | Çözmeden önce kazınan değeri yazdırın. Ayrıntılar şurada: ERROR_GOOGLEKEY hatasını düzeltme |
ERROR_BAD_PARAMETERS | data-s boş bir dize olarak gönderildi ya da Google dışı bir sayfaya gönderildi | Yalnızca öznitelik gerçekten mevcut olduğunda iletin |
ERROR_CAPTCHA_UNSOLVABLE | Genellikle bayatlamış bir data-s: sayfa, çözümden dakikalar önce çekilmiş | Sayfayı çekip hemen ardından çözün. Bakın: ERROR_CAPTCHA_UNSOLVABLE |
| Token çözücü tarafından kabul edildi, Google tarafından reddedildi | Çekme ile gönderme arasında farklı çerezler veya farklı bir IP | Tek bir session'ı yeniden kullanın ve ikisi için de aynı proxy'yi kullanın |
NetworkException | CapSkip çalışmıyor | Uygulamayı başlatın, ayarlardan portu doğrulayın |
Her parametre ve yanıt biçimi şurada listelenmiştir: API dokümantasyonu.
Sık sorulan sorular
Normal bir web sitesinde data-s gerekli mi?
Hayır. Yalnızca Google'ın kendi sayfalarında görünür. Eğer data-s HTML'de yoksa, argümanı tamamen dışarıda bırakın ve bunu standart bir v2 challenge'ı olarak, reCAPTCHA v2 çözücü sayfasında anlatıldığı gibi çözün.
data-s, Enterprise bayrağıyla aynı şey mi?
Hayır, ikisi birbirinden bağımsızdır. enterprise=1 çözücüye hangi reCAPTCHA ürünüyle uğraştığını söyler. datas sayfadan gelen tek kullanımlık bir değer taşır. Google Arama challenge'ı ikincisine ihtiyaç duyar ve bir sayfa gerçekten gerektiriyorsa ikisini birden iletebilirsiniz.
Değer ne kadar süre geçerli kalır?
Dakikalar değil, saniyeler varsayın. Sayfayla birlikte üretilir ve sayfayla birlikte ölür. Kazıyıcınız sayfaları kuyruğa alıp sonradan çözüyorsa, değeri saklamak yerine çözüm anında sayfayı yeniden çekin.
Neden kodda datas, HTML'de ise data-s?
Çünkü bir tire, Python anahtar sözcük argümanında ya da C# tanımlayıcısında yer alamaz. SDK'lar tireyi düşürür ve tireli adı sizin yerinize hat üzerinden gönderir. Ham in.php çağrısı hâlâ şunu bekler: data-s.
Özet
Şunları kazıyın: data-sitekey ve data-s ikisi de aynı elemanda. İkincisini şu adla iletin: datas, ardından token'ı aynı session üzerinden birkaç dakika içinde gönderin. Bu üçünden birini atlarsanız, sorunsuz görünen ama başarısız olan bir token elde edersiniz.
Python tarafının kalanı Python CAPTCHA çözücü sayfasında. CapSkip bunların hepsini yerel bir captcha atlatma servisi olarak kendi makinenizde yapar; bu yüzden taze bir değer almak için bir sayfayı iki kez kazımak size istekten başka hiçbir maliyet getirmez.
