2016-08-25 16 views
10

私は、ユーザーが検索値とキャプチャを入力する必要があるサイトを削り取ろうとしています。私は時間の約33%を成功させるキャプチャのための光学式文字認識(OCR)ルーチンを持っています。 captchaは常にアルファベットのテキストなので、OCR関数がアルファベット以外の文字を返す場合はcaptchaをリロードする必要があります。テキスト「単語」を取得したら、検索フォームを提出したいと思います。キャプチャを扱うためにScrapyを設定するには

結果が同じページに戻ってきます。フォームは新しい検索と新しいcaptchaの準備ができています。だから、私は検索条件を使い果たすまですすぎと繰り返しをする必要があります。

ここではトップレベルのアルゴリズムがあります:

  1. ロードページ最初は
  2. OCRは、テキストのみの結果で戻ってきていない場合はOCR
  3. を通してそれを実行し、キャプチャ画像をダウンロードキャプチャを更新してこの手順を繰り返してください。
  4. 検索語とキャプチャのあるページでクエリフォームを送信してください
  5. キャプチャが正しいかどうかを確認してください。
  6. それが正しい場合
  7. は、2

にデータ

  • ゴーをこすり、私は、キャプチャを取得するためのパイプラインを使用してみましたが、その後私は、フォーム送信のための値を持っていません。 urllibなどを使用してフレームワークを経由せずにイメージを取得しただけの場合、セッションでのCookieは送信されないため、サーバー上のcaptchaの検証は失敗します。

    これを行うための理想的な治療方法は何ですか?

  • 答えて

    7

    これは、一連の解決策では本当に深い話題です。しかし、投稿に定義したロジックを適用したい場合は、Downloader Middlewaresのscrapを使用することができます。以下のような

    何か:

    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 
    

    この例では、すべての応答を傍受し、キャプチャを解決しようとします。失敗した場合、新しいcaptchaのページを再試行し、成功した場合は解決されたcaptcha値を持つレスポンスにいくつかのメタキーを追加します。
    あなたのスパイダーでは次のように使用します:

    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 
    
    関連する問題