Scrapy indirme ara katmanında solvethree'yi kullanın

solvethree tarafından4 dk okuma

Yalnızca spider'ınızın açıkça işaretlediği istekler için çözüm üretmek üzere asenkron bir indirme ara yazılımı kullanın. Senkron solvethree SDK'sını bir çalışan iş parçacığında çalıştırın, ardından token'ı, proxy'yi ve döndürülen tarayıcı kimliğini içeren bir FormRequest döndürün.

Örnek, yapılandırılmış tek bir reCAPTCHA Enterprise form uç noktasını işler. Doğrulama görevlerini algılamaz veya herhangi bir web sitesinin token'ı nasıl beklediğini keşfetmez.

Bu sayfada

Ara yazılımı etkinleştirmeden önce hedefi yapılandırın

  • Scrapy 2.19+, Python 3.10+ ve resmi solvethree Python SDK'sını kullanın. SDK senkrondur; yerel asenkron istemcisi yoktur.
  • Konsolda çalışma alanınız için etkin bir site profili oluşturun. Ana makine adı ve eylem göndermek profil oluşturmaz. Site profili kurulumu sayfasına bakın.
  • TARGET_URL değerini tam form gönderim URL'sine, SOLVETHREE_PROXY değerini bu uygulama isteği için kullanılan proxy'ye ve SOLVETHREE_API_KEY değerini çalışma alanı anahtarınıza ayarlayın. Anahtarı sunucu tarafında tutun.
  • Aşağıda gösterildiği gibi AsyncioSelectorReactor'ı etkinleştirin ve ara yazılımı 740 önceliğiyle kaydedin. Böylece 750 önceliğindeki HttpProxyMiddleware'den önce yer alır.

Yalnızca açıkça işaretlenmiş istekler için çözüm üretin

Scrapy · yalnızca açıkça işaretlenmiş form isteklerini çözme
# middlewares.py; Scrapy 2.19+, Python 3.10+, official solvethree SDK.
import asyncio
import os
from urllib.parse import urlsplit
from scrapy.http import FormRequest
from solvethree import Solvethree

class CaptchaMiddleware:
    async def process_request(self, request):
        if not request.meta.get("solvethree_form") or request.meta.get("solvethree_applied"):
            return None
        target = os.environ["TARGET_URL"]
        if request.url != target:
            raise ValueError("Only the configured form target may use this middleware")
        proxy = os.environ["SOLVETHREE_PROXY"]
        def solve():
            return Solvethree(os.environ["SOLVETHREE_API_KEY"]).solve({
                "site": urlsplit(target).hostname, "action": "login", "proxy": proxy,
                "requestId": request.meta["solvethree_request_id"],
            }, timeout=180)
        result = await asyncio.to_thread(solve)
        solution = result["solution"]
        fields = dict(request.meta["solvethree_fields"])
        fields["g-recaptcha-response"] = solution["token"]
        meta = {**request.meta, "proxy": proxy, "solvethree_applied": True,
                "dont_retry": True, "dont_redirect": True}
        return FormRequest(target, formdata=fields, callback=request.callback,
            errback=request.errback, headers={"User-Agent": solution["userAgent"],
                "sec-ch-ua": solution["secChUa"]}, meta=meta, dont_filter=True)

# settings.py:
# TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor"
# DOWNLOADER_MIDDLEWARES = {"myproject.middlewares.CaptchaMiddleware": 740}
# The spider first loads its form/CSRF data with the same proxy and cookiejar.
# Then yield a Request(TARGET_URL, callback=your_result_handler, meta={
#     "solvethree_form": True, "solvethree_request_id": one_saved_logical_job_id,
#     "solvethree_fields": {"csrf": token_from_the_form, "email": "your-test-value"},
#     "cookiejar": your_cookiejar_id,
# })
# Inspect the final response in your_result_handler; a ready task is not that response.

Ara yazılımın process_request metodu, kullanımdan kaldırılmış spider argümanı olmadan yalnızca request alır. İşaretlenmemiş istekler değiştirilmeden geçer. İşaretli bir istek TARGET_URL ile tam olarak eşleşmelidir; eşleşmezse başka bir uç noktaya token göndermek yerine hata oluşturulur.

asyncio.to_thread, senkron SDK'nın ağ çağrılarını ve durum sorgulamalarını olay döngüsü iş parçacığının dışında tutar. Yalnızca process_request metodunu async olarak tanımlamak bunu sağlamaz. SDK bir görev oluşturur ve sonuç hazır olana kadar bekler veya istisna fırlatır; ardından ara yazılım form gönderimini oluşturur.

Uygulamanızın gerçekten gönderdiği formla eşleştirin

  1. 1.

    Doğru eylemi ve token alanını ayarlayın

    Örnek, login eylemini kullanır ve solution.token değerini g-recaptcha-response alanına yerleştirir. Bunları hedefin entegrasyonuna uyacak şekilde değiştirin. Görevin site alanı, TARGET_URL'nin ana makine adından türetilir; reCAPTCHA görevleri type veya url alanlarını almaz. recaptchaType belirtilmezse enterprise-v3 seçilir.

  2. 2.

    Mevcut form alanlarını sağlayın

    Spider, solvethree_fields alanını uç noktanın güncel CSRF değeri dahil gerekli alanlarıyla doldurmalıdır. Ara yazılım bu alanları kopyalar ve token'ı ekler; formu yüklemez veya gizli girdileri çıkarmaz.

  3. 3.

    Oturumu tutarlı tutun

    İlk formu, uygulamanın gerektirdiği aynı proxy ve tarayıcı kimliği üzerinden yükleyin. Formun cookiejar kimliğini işaretli isteğin meta verilerinde iletin. Döndürülen FormRequest bu cookiejar'ı korur ve solution.userAgent ile solution.secChUa değerlerini kullanır ancak örnek önceki oturumu hazırlamaz veya onarmaz.

  4. 4.

    Uygulama yanıtını ele alın

    Form gönderiminin başarılı olup olmadığını kontrol eden bir callback ve istek hataları için bir errback sağlayın. Hazır bir görev, bir çözüm üretildiği anlamına gelir; web sitesinin sonraki isteği kabul ettiği anlamına gelmez.

Bu örnek, çözüm ve gönderim için özellikle tek bir proxy kullanır. Çözümden sonra bunu ilgisiz bir proxy ile değiştirmeyin. Ayrıca User-Agent veya istemci ipuçlarını yeniden yazan özel indirme ara yazılımlarını inceleyin: çözümle birlikte döndürülen kimliğin üzerine yazmamalıdır.

Yeniden denemelerin başka bir çözüm başlatmasını önleyin

İşaretli isteği yield ile vermeden önce solvethree_request_id değerini kaydedin ve aynı mantıksal çözüm işlemi için koruyun. requestId, 1–64 ASCII harfi, rakam, alt çizgi veya kısa çizgi kabul eder. Bunu birebir aynı görev girdileriyle yeniden kullanmak mevcut görevi kurtarır; kimliği koruyup girdileri değiştirmek çakışmaya yol açar.

Döndürülen FormRequest, başka bir çözümü tetiklememek için solvethree_applied değerini ayarlar. Ayrıca dont_retry ve dont_redirect değerlerini ayarlayarak bu gönderim için otomatik yeniden denemeleri ve yönlendirmeleri önler. Bu bayraklar, kendi callback'inizin veya iş çalıştırıcınızın başka bir istek başlatmasını engellemez; bu nedenle bu kararı açıkça verin.

Çözüm çağrısı zaman aşımına uğrar.

Bir görevin zaten oluşturulup oluşturulmadığını belirleyin. Bağlantı zaman aşımı, oluşturmanın başarısız olduğunu kanıtlamaz.

Şunu deneyin: Yeni bir mantıksal çözüm isteği oluşturmadan önce bilinen görevi alın veya kayıtlı requestId ve aynı görev girdileriyle görevi kurtarın.

Çözüm işlemi sonuç döndürmek yerine istisna fırlatıyor.

HTTP isteği hatasını, son duruma ulaşmış bir görev başarısızlığından ayırt edin. Başarısız bir görev için errorCode ve error alanlarını inceleyin.

Şunu deneyin: Aynı işaretli isteği tekrar tekrar üretmek yerine hatayı ele alın. Yeniden denemeden önce geçersiz girdileri düzeltin; başarısız görevler için durum sorgulamaya devam edilmemelidir.

Web sitesi gönderilen formu reddediyor.

Önce giden token alanını, CSRF alanlarını, çerezleri, proxy'yi ve tarayıcı kimliğini inceleyin.

Şunu deneyin: Başka bir çözüm için ödeme yapmadan önce uygulama isteğini düzeltin. Alan, görev kimliğini veya eski bir token'ı değil, solution.token değerini içermelidir.

İlk görevinizi çalıştırın.

$5 çalışma alanı kredisiyle başlayın.

Çalışma alanı oluşturun
Scrapy indirme ara katmanında solvethree'yi kullanın · solvethree