2016-08-25 86 views
10

Kullanıcının arama değerini ve captcha'yı girmesini gerektiren bir siteyi taramaya çalışıyorum. Captcha için zamanın% 33'ünü aşan bir optik karakter tanıma (OCR) rutinim var. Captcha'lar her zaman alfabetik metin olduğundan, OCR işlevi alfabetik olmayan karakterler döndürdüğünde captcha'yu yeniden yüklemek istiyorum. Bir metin "kelimesi" aldığımda, arama formunu göndermek istiyorum.Bir captcha ile başa çıkmak için Scrapy'yi nasıl kurarım

Sonuçlar, yeni bir arama için hazır form ve yeni bir captcha ile aynı sayfaya geri gelir. Bu yüzden arama terimlerimi tüketene kadar durulayıp tekrar etmem gerekiyor. OCR salt metin neden geri gelmezse başlangıçta

  • , kaptan görüntüyü indir OCR
  • aracılığıyla çalıştırmak

    1. Yük sayfa: İşte

      üst düzey algoritması var , kaptan doğru olup olmadığını görmek için yanıtı kontrol arama terimi ve Captcha
    2. ile sayfaya sorgu formu gönder captcha'yı yenileyip bu adımı
    3. tekrarlayın
    4. Doğru olsaydı
    5. , veri
    6. Git Ben captcha'yı almak için bir boru hattı kullanarak denedim ama sonra form gönderimine ilişkin değeri olmayan 2

    için kazıyın. Çerçeveden geçmeden urllib veya başka bir şey kullanmadan görüntüyü getirirsem, oturumla birlikte tanımlama bilgisi gönderilmez, dolayısıyla sunucudaki captcha doğrulaması başarısız olur.

    Bunu yapmanın en iyi yolu nedir?

  • cevap

    7

    Bir sürü çözümle gerçekten derin bir konu. Ancak, postanızda tanımladığınız mantığı uygulamak isterseniz, scrub Downloader Middlewares'u kullanabilirsiniz. gibi

    şey: Bu örnek her yanıtını yakalamak ve captcha'yı çözmeye çalışacağı

    class CaptchaMiddleware(object): 
        max_retries = 5 
        def process_response(request, response, spider): 
         if not request.meta.get('solve_captcha', False): 
          return response # only solve requests that are marked with meta key 
         catpcha = find_catpcha(response) 
         if not captcha: # it might not have captcha at all! 
          return response 
         solved = solve_captcha(captcha) 
         if solved: 
          response.meta['catpcha'] = captcha 
          response.meta['solved_catpcha'] = solved 
          return response 
         else: 
          # retry page for new captcha 
          # prevent endless loop 
          if request.meta.get('catpcha_retries', 0) == 5: 
           logging.warning('max retries for captcha reached for {}'.format(request.url)) 
           raise IgnoreRequest 
          request.meta['dont_filter'] = True 
          request.meta['captcha_retries'] = request.meta.get('captcha_retries', 0) + 1 
          return request 
    

    . Başarısız olsaydı, yeni captcha için sayfayı yeniden dener, eğer başarılı olursa, çözülmüş captcha değerleriyle yanıt vermek için bazı meta anahtarlar ekler.
    Örümcekinizde şu şekilde kullanabilirsiniz:

    class MySpider(scrapy.Spider): 
        def parse(self, response): 
         url = ''# url that requires captcha 
         yield Request(url, callback=self.parse_captchad, meta={'solve_captcha': True}, 
             errback=self.parse_fail) 
    
        def parse_captchad(self, response): 
         solved = response['solved'] 
         # do stuff 
    
        def parse_fail(self, response): 
         # failed to retrieve captcha in 5 tries :(
         # do stuff