Scrapling'de page_action ile CAPTCHA Nasıl Çözülür

Bir Scrapling captcha işi net biçimde ikiye ayrılır ve hangi yarıda olduğunuzu bilmek size bir öğleden sonra kazandırır. Cloudflare'ın kendi anahtarı var: StealthyFetcher'a solve_cloudflare verin, Turnstile veya ara sayfa doğrulaması sizin için halledilsin. Geri kalan her şey size kalmış. reCAPTCHA v2, reCAPTCHA v3, GeeTest ve görüntü CAPTCHA'ları fetcher'ın dışında çözülür ve page_action kancası üzerinden sayfaya enjekte edilir. Bu yazı, sessizce her şeyi bozan o tek ayrıntı dahil, ikinci yarıyı adım adım anlatıyor.
Neye ihtiyacınız var
- Python 3.10 veya daha yenisi. Scrapling bunu gerektiriyor.
- fetchers ekstrasıyla kurulmuş Scrapling ve onun tek seferlik tarayıcı indirme adımı.
- Korumalı sayfanın URL'si. sitekey'i baştan bilmeniz gerekmez, çünkü ilk geçiş onu okur.
- Kazıyıcı ile çözücü aynı makineyi paylaşıyorsa Local modunda, paylaşmıyorsa Server modunda çalışan CapSkip. Her ikisi de şurada anlatılıyor: bağlantı ayarları.
# pip install capskip pip install capskip pip install "scrapling[fetchers]" # Scrapling needs one more step. The bare package is the parser # engine only, and importing from scrapling.fetchers without this # raises ModuleNotFoundError. scrapling install
solve_cloudflare neyi kapsar, neyi kapsamaz
Bu konuda net olmakta fayda var, çünkü isim özelliğin kendisinden daha geniş duruyor. StealthyFetcher’ın solve_cloudflare argümanı, yanıtı size vermeden önce Cloudflare’ın Turnstile ve ara sayfa doğrulamalarını aşar. Bu gerçek bir kolaylık ve kullanmalısınız. Listenin tamamı da bundan ibaret.
| Sayfadaki doğrulama | Kim halleder |
|---|---|
| Cloudflare Turnstile ve tam sayfa ara doğrulama | Scrapling, solve_cloudflare argümanı üzerinden |
| reCAPTCHA v2, invisible ve enterprise varyantları dahil | Siz, bir page_action kancası üzerinden |
| action adı olan reCAPTCHA v3 | Siz, bir page_action kancası üzerinden |
| GeeTest v3, yanıtında üç alan bulunan kaydırıcı | Siz, bir page_action kancası üzerinden |
| Bozuk metinli bir görüntü CAPTCHA'sı | Siz, bir page_action kancası üzerinden |
Yani işin biçimi her seferinde aynı. Doğrulama parametrelerini sayfadan çıkarın, başka bir yerde çözün, sonra yanıtı DOM’a geri koyup sitenin kendi formunun taşımasına izin verin. Scrapling ortadaki o parçayı yapmanız için size tam olarak tek bir yer verir: page_action.
Adım 1: tarayıcı başlatmadan sitekey'i okuyun
Scrapling'in üç fetcher'ı var ve bunlar birbirinin yerine geçmez. Fetcher düz HTTP'dir. DynamicFetcher bir Playwright tarayıcısı sürer. StealthyFetcher sertleştirilmiş olandır ve 0.3.13 sürümünden beri daha önce kullandığı Camoufox yapısı yerine Patchright üzerinde çalışır; eski bir rehberi takip ediyorsanız bunu bilmekte fayda var.
Bir sitekey için neredeyse hiçbir zaman tarayıcıya ihtiyacınız olmaz. Değer, işaretlemede bir data özniteliği olarak durur; bu yüzden ucuz fetcher onu okuyabilir.
# pip install capskip
from scrapling.fetchers import Fetcher
PAGE_URL = "https://example.com/page-with-recaptcha"
# Plain HTTP. No browser starts, so this costs almost nothing
# and tells you which CAPTCHA you are actually facing.
page = Fetcher.get(PAGE_URL)
sitekey = page.css("[data-sitekey]::attr(data-sitekey)").get()
print(sitekey)Bu boş dönerse, widget JavaScript ile yazılıyordur ve sunulan HTML'de yoktur. Aynı sayfayı bir kez DynamicFetcher ile çekip render edilmiş DOM'dan okuyun ya da tarayıcıda açıp değeri koda gömün. Bir sitekey herkese açıktır ve sabittir; dolayısıyla onu koda gömmek özür dilemeniz gereken bir kestirme yol değildir.
Adım 2: kendi donanımınızda çözün
Tek çağrı. Her reCAPTCHA varyantı, farklı anahtar kelime argümanlarıyla aynı metottur: invisible 1 yapılır, enterprise 1 yapılır ya da version v3 yapılıp bir action adı verilir. Turnstile ve GeeTest'in aynı biçimde kendi metotları vardır ve tam parametre listesi şuradadır: CapSkip API dokümantasyonu.
# CapSkip listens on your own machine, so this is a loopback call. from capskip import CapSkip solver = CapSkip(host="127.0.0.1", port=8080) token = solver.recaptcha(sitekey=sitekey, url=PAGE_URL)["code"]
O çağrı yoklama yaparken bloklar ve yoklama sabit aralıklı değildir: SDK 250 milisaniyeden başlar ve pollingInterval değerine doğru geri çekilir; bu yüzden genellikle ham uç noktaya karşı elle yazılmış bir döngüden daha erken döner. Üst sınır recaptchaTimeout'tur ve varsayılanı 300 saniyedir.
Adım 3: token'ı page_action içinde enjekte edin
page_action bir fonksiyon alır, Playwright page nesnesini bu fonksiyona geçirir ve gezinmeden ve network_idle beklemesinden sonra, ancak wait_selector'dan önce çalışır. İşe yarayan kısım bu sıralama: fonksiyonunuz çalıştığında widget render edilmiş olur ve sonrasında beklediğiniz her şey yaptığınız şeyin sonucunu görür.
from playwright.sync_api import Page
def inject_token(page: Page):
# The response textarea is hidden, so set the value directly
# rather than trying to type into it.
page.evaluate(
"(t) => document.getElementById('g-recaptcha-response').value = t",
token,
)
page.click("button[type=submit]")Fonksiyonun bir şey döndürmesi gerekmez. Scrapling'in eski sürümleri page nesnesinin geri verilmesini isterdi, güncel dokümantasyon istemiyor; bu yüzden hiçbir şey döndürmemek her iki durumda da güvenli yazımdır.
Asıl canınızı yakan kısım: izole yürütme bağlamı
StealthyFetcher, JavaScript kodunuzu varsayılan olarak Patchright’ın izole yürütme bağlamında değerlendirir. DOM paylaşılır; bu yüzden öğeleri okumak ve yazmak tam beklediğiniz gibi çalışır. Sayfanın kendi JavaScript global değişkenleri paylaşılmaz; dolayısıyla sitenin window üzerine koyduğu her şey basitçe yoktur.
Enjeksiyonunuzun işe yarayıp yaramayacağını bu ayrım belirler. Yanıt textarea’sının değerini ayarlamak yalnızca DOM’a dokunur ve izole dünyada sorunsuz çalışır. Sitenin reCAPTCHA callback’ini çağırmak çalışmaz, çünkü o callback sayfanın kendi betiğinin oluşturduğu bir global üzerinde yaşar. Sıradan bir form gönderimi yerine callback kullanan siteler, gayet geçerli bir token’ı yok saymış gibi görünecektir.
def inject_and_fire_callback(page: Page):
# isolated_context=False drops into the page's own world,
# where the site's grecaptcha object actually exists.
page.evaluate(
"""(t) => {
document.getElementById('g-recaptcha-response').value = t;
window.onCaptchaSuccess(t);
}""",
token,
isolated_context=False,
)Bunu yazmadan önce callback adını widget'tan okuyun. reCAPTCHA öğesindeki data-callback özniteliği ne diyorsa odur ve siteden siteye değişir.
Tam çalışan örnek
sitekey'i okumak için ucuz bir HTTP geçişi, bir çözüm, ardından enjekte edip gönderen tek bir stealthy fetch. Çözümün fetch'ten önce gerçekleştiğine dikkat edin; böylece page_action çalıştığında token çoktan elinizdedir.
# pip install capskip
from capskip import CapSkip
from playwright.sync_api import Page
from scrapling.fetchers import Fetcher, StealthyFetcher
PAGE_URL = "https://example.com/page-with-recaptcha"
solver = CapSkip(host="127.0.0.1", port=8080)
sitekey = Fetcher.get(PAGE_URL).css("[data-sitekey]::attr(data-sitekey)").get()
token = solver.recaptcha(sitekey=sitekey, url=PAGE_URL)["code"]
def inject_token(page: Page):
page.evaluate(
"(t) => document.getElementById('g-recaptcha-response').value = t",
token,
)
page.click("button[type=submit]")
page = StealthyFetcher.fetch(
PAGE_URL,
headless=True,
network_idle=True,
page_action=inject_token,
wait_selector=".dashboard",
)
print(page.css(".dashboard h1::text").get())Orada iki argüman taşıyıcı rol oynuyor. network_idle, fetcher'ı 500 milisaniye boyunca hiç ağ bağlantısı olmayana kadar bekletir ki bu genellikle widget'ın render edilmesine yeter. wait_selector ise gönderimin işe yaradığını kanıtlayan şeydir: onu yalnızca formun öbür tarafında var olan bir şeye yöneltin, böylece başarısız bir gönderim sessiz bir başarı yerine zaman aşımına dönüşür.
Bir oturumla birden fazla sayfa işlemek
Sınıf düzeyindeki her fetch bir tarayıcı başlatır ve sonra onu atar. Birkaç sayfadan fazlası için bunun yerine bir oturum açın ve tarayıcıyı istekler arasında açık tutun. Çoğu fetch argümanı oturum üzerinde bir kez ayarlanabilir ve istek başına geçersiz kılınabilir; page_action, wait_selector ve solve_cloudflare dahil.
from scrapling.fetchers import StealthySession
# solve_cloudflare here handles the Cloudflare layer for every
# page in the session. Anything else still goes through
# page_action, per request.
with StealthySession(headless=True, solve_cloudflare=True) as session:
for url in urls:
page = session.fetch(url, page_action=inject_token)
print(page.css("title::text").get())Olabildiğince geç çözün. Bir reCAPTCHA token'ı yaklaşık iki dakika geçerlidir; bu yüzden yirmi tanesini baştan çözüp sonra bir kuyrukta ilerlemek çoğunun süresini doldurur. Döngünün içinde, onu kullanan fetch'ten hemen önce çözün. Bu ömrün pratikte ne anlama geldiği şurada ele alınıyor: reCAPTCHA token ömrü kılavuzu.
Çözücüyü başka bir makinede çalıştırmak
Kazıyıcılar yer değiştirir. Bir VPS, bir konteyner veya zamanlanmış bir işçi, çözücünün bulunduğu makine değildir ve oradaki loopback adresi, hiçbir şeyin dinlemediği işçinin kendisini gösterir.
CapSkip'in tam olarak bunun için iki bağlantı modu var. Local, 127.0.0.1 adresine bağlanır ve yalnızca o cihaza yanıt verir. Server ise ağ adresinize veya genel IP'nize bağlanır; böylece herhangi bir yerdeki kazıyıcı aynı Windows makinesine API üzerinden ulaşabilir. Statik bir genel IP, adresi sabit tutar. Her iki durumda da donanım sizindir ve her iki durumda da ölçümsüzdür; dolayısıyla elli bin doğrulama çözen bir koşu, elli tane çözenle aynı maliyettedir.
# The SDK reads these three itself, so the same script runs # whether the solver is on this box or on another one: # CAPSKIP_HOST=192.0.2.10 # CAPSKIP_PORT=8080 # CAPSKIP_API_KEY=your-key solver = CapSkip()
Çözücü bir ağ adresini dinlemeye başladığında anahtar doğrulamayı açın ve her işçiye kendi anahtarını verin ki biri, diğerlerini rahatsız etmeden iptal edilebilsin. Her iki mod da şurada adım adım anlatılıyor: CapSkip kurulum kılavuzu.
Her iki uçta proxy
Site, token'ın onu gönderen adresten geldiğini kontrol ediyorsa, çözüm ile fetch aynı çıkıştan ayrılmalıdır. Scrapling fetcher'larda bir proxy argümanı alır; CapSkip ise reCAPTCHA, Turnstile ve GeeTest için görev başına bir tane alır. Görüntü CAPTCHA'ları proxy kabul etmez ve buna ihtiyaç duymaz.
PROXY = "http://user:[email protected]:3128" token = solver.recaptcha( sitekey=sitekey, url=PAGE_URL, proxy={"type": "HTTP", "uri": "user:[email protected]:3128"}, )["code"] page = StealthyFetcher.fetch(PAGE_URL, proxy=PROXY, page_action=inject_token)
İki yazım bilerek farklı: çözücü, türü ve URI'yi ayrı alanlar olarak alır, fetcher tek bir URL dizesi alır. Bunlardan birini yanlış yapmak, çözümün gerçek adresinizden, fetch'in ise proxy üzerinden çıkması demektir; bu da tıpatıp bozuk bir token gibi görünür ama öyle değildir. Proxy türü seçimi şurada ele alınıyor: çözüm sırasında proxy döndürme kılavuzu.
Sık görülen hatalar ve anlamları
| Gördüğünüz | Neden | Düzeltme |
|---|---|---|
| fetchers içe aktarımında ModuleNotFoundError | Çıplak paket yalnızca ayrıştırıcı motordur | fetchers ekstrasıyla kurun, sonra scrapling install komutunu çalıştırın |
| sitekey seçicisi hiçbir şey döndürmüyor | Widget JavaScript ile enjekte ediliyor, bu yüzden sunulan HTML'de yok | Bir kez DynamicFetcher ile okuyun ya da koda gömün |
| Token alana düşüyor ama form hiç gönderilmiyor | Site bir callback kullanıyor ve o global, izole dünyada yok | evaluate çağrısında isolated_context değerini False olarak verin |
| Temiz bir çözümden sonra wait_selector'da zaman aşımı | Gönderim başarısız oldu, bu yüzden öbür taraftaki öğe hiç görünmedi | page_action içinde ekran görüntüsü alın ve sayfanın gerçekte ne dediğine bakın |
| Geçerli bir token reddediliyor | Çözüm ile fetch farklı adreslerden çıktı | Her ikisine de aynı proxy’yi koyun, her birinin kendi yazımıyla |
| Çözücüden NetworkException | CapSkip çalışmıyor ya da host ve port yanlış | Uygulamayı başlatın ya da host ortam değişkenini sunucu adresine yöneltin |
| Çözücüden ValidationException | O CAPTCHA türünün kabul etmediği bir argüman | Türü kontrol edin. v2'de action ya da v3'te invisible bunu tetikler |
FAQ
solve_cloudflare reCAPTCHA'yı da halleder mi?
Hayır. Cloudflare’ın Turnstile widget’ını ve Cloudflare’ın ara doğrulama sayfasını kapsar; bunlar Cloudflare ürünleridir. reCAPTCHA Google’ındır, GeeTest kendine aittir ve görüntü CAPTCHA’sı sitenin çizdiği her neyse odur. Bu üçü, kendi çözdüğünüz bir token ile page_action üzerinden geçer.
StealthyFetcher hâlâ Camoufox üzerine mi kurulu?
0.3.13 sürümünden beri değil. Artık bir Firefox yığını yerine Chromium yığını olan Patchright üzerinde çalışıyor. Dokümantasyon hâlâ oturumu alt sınıflayarak Camoufox'a geri dönmek için isteğe bağlı bir tarif anlatıyor, ama varsayılan değişti; dolayısıyla size StealthyFetcher'ın bir Camoufox sarmalayıcısı olduğunu söyleyen bir rehber, daha eski bir sürümü anlatıyordur.
Fetch'ten önce değil de page_action içinde çözebilir miyim?
Çözebilirsiniz ve reCAPTCHA v3 ya da GeeTest için çoğu zaman mecbursunuz, çünkü parametreler ancak sayfa çalıştıktan sonra var olur. Yalnızca şunu unutmayın: tarayıcı çözüm boyunca boşta bekliyor olur. sitekey sunulan HTML'deyse, önce çözüp sonra enjekte etmek tarayıcıyı bunun küçük bir kısmı kadar süre açık tutar.
Async fetcher bunların herhangi birini değiştirir mi?
Yalnızca yazımı. Async fetch metodunu kullanın ve page_action'ı, async Playwright page nesnesini alan bir async fonksiyon yapın. Çözücü tarafında AsyncCapSkip kullanın; bu, Python'da bir takma ad değil gerçek bir async uygulamadır, dolayısıyla bir iş parçacığını park etmek yerine sizin olay döngünüzü paylaşır.
Kısa özet
Cloudflare'ı solve_cloudflare ile Scrapling'e bırakın, geri kalan her şeyi page_action içinde kendiniz halledin. sitekey'i düz HTTP fetcher ile okuyun, çözün, sonra yanıt alanını kancanın içinden ayarlayın. Site, form göndermek yerine bir callback tetikliyorsa izole bağlam kapalı olarak değerlendirin; yoksa token, sayfanın göremediği bir dünyaya düşer. wait_selector'ı yalnızca başarılı bir gönderimden sonra var olan bir şeye yöneltin ki başarısızlık sesli olsun.
Daha geniş Python hikâyesi şurada: Python CAPTCHA çözücü sayfası, onay kutusu doğrulamasının ayrıntıları şurada: reCAPTCHA v2 çözücü sayfası, Cloudflare tarafı ise şurada: Cloudflare Turnstile çözücü sayfasını. Aynı üç çağrı Node.js, PHP ve C# içinde de var; listesi şurada: CAPTCHA çözme SDK sayfası.
Bunu gerçek bir taramaya yöneltmeden önce tartılması gereken bir şey var. CapSkip, zaten sahip olduğunuz donanımda çalışan bir sınırsız captcha çözücü olduğundan, büyük bir kazımanın CAPTCHA kalemi çözüm başına değil sabit bir maliyettir.
