2011-07-11 12 views
6

私は、キャプチャを使用するフォーム(これはスパムではありません)でサイトにログインしようとしているScrapyアプリケーションに取り組んでいます。私はImagesPipelineを使用してキャプチャをダウンロードしています。ユーザーが解決できるように画面に印刷しています。ここまでは順調ですね。Captchas in Scrapy

私の質問は、どのようにキャプチャ/フォーム情報を送信するために、スパイダーを再起動することができますか?現在、私のスパイダーはキャプチャのページを要求し、Itemには、キャプチャのimage_urlが含まれています。これはImagesPipelineによって処理/ダウンロードされ、ユーザーに表示されます。スパイダーの進捗状況を再開する方法が不明で、captchaと同じセッションをスパイダーに渡すと、ImagesPipelineが動作する前にスパイダーがアイテムを返さなければならないと考えられます(終了するなど)。

私はドキュメントと例を見てきましたが、これをどうやって行うかを明確にしたものは見つかりませんでした。

答えて

5

これはあなたがどのようにかもしれないスパイダーの内部で動作するようになる。あなたが要求を取得すると

self.crawler.engine.pause() 
process_my_captcha() 
self.crawler.engine.unpause() 

、エンジンを一時停止し、画像を表示し、ログインのPOSTリクエストを提出することによって、クロールを再開&ユーザーからの情報をお読みください。

あなたのケースでアプローチが有効かどうかを知りたいと思います。

+0

どのようにImagesPipelineをクローラコード内から呼び出すのですか? –

+0

あなたはあなたのスパイダーで解析したページからイメージを取り込むことができます。私はImagesPipelineでそれを試していません – Medorator

+0

frisoからのアイデア。手動でそれを処理したい場合は - > はデフ解析(自己、応答): self.crawler.engine.pause() captcha_var = raw_input( "コピーキャプチャ:") self.crawler.engine.unpause() リターンscrapy.FormRequest.from_response( 応答、 FORMDATA = { 'codeTextBox':captcha_var} = self.after_login コールバック) DEF after_login(自己、応答): プリント(response.body) リターン – OWADVL

3

私はItemを作成せずにImagePipelineを使用します。

import urllib 
import os 
import subprocess 

... 

def start_requests(self): 
    request = Request("http://webpagewithcaptchalogin.com/", callback=self.fill_login_form) 
    return [request]  

def fill_login_form(self,response): 
    x = HtmlXPathSelector(response) 
    img_src = x.select("//img/@src").extract() 

    #delete the captcha file and use urllib to write it to disk 
    os.remove("c:\captcha.jpg") 
    urllib.urlretrieve(img_src[0], "c:\captcha.jpg") 

    # I use an program here to show the jpg (actually send it somewhere) 
    captcha = subprocess.check_output(r".\external_utility_solving_captcha.exe") 

    # OR just get the input from the user from stdin 
    captcha = raw_input("put captcha in manually>") 

    # this function performs the request and calls the process_home_page with 
    # the response (this way you can chain pages from start_requests() to parse() 

    return [FormRequest.from_response(response,formnumber=0,formdata={'user':'xxx','pass':'xxx','captcha':captcha},callback=self.process_home_page)] 

    def process_home_page(self, response): 
     # check if you logged in etc. etc. 

...

私はここでやっていることは、外部のコマンドラインユーティリティを呼び出すために(、(画像を保存するために))私はurllib.urlretrieve(urlをインポートすることであるos.remove(file)(前の画像を削除する)、およびsubprocess.checoutputキャプチャを解決するために)。このようなキャプチャを解決することは常にハックであるため、この「ハック」ではScrapyインフラストラクチャ全体が使用されません。

このような全体的な外部のサブプロセスの事は、1つの方がいいかもしれませんが、これは動作します。

いくつかのサイトでは、captchaイメージを保存することはできません。ブラウザでページを呼び出し、screen_captureユーティリティを呼び出して正確な場所をトリミングしてキャプチャを切り取る必要があります。今はスクリーンスクレイピングです。