2017-04-12 9 views
1

私はscrapyを使用して、認証付きウェブサイトをクロールしています。
は、私は、クローラの状態を保存できるようにしたいと私は同じコマンドを使用して再開した後、私は私が保存されてすべてをそれ前にウェブサイトにログインできるようにしたい再スケジュール治療は何かを再開する前に行う

scrapy crawl myspider -s JOBDIR=mydir 

を使用しますリクエスト。

基本的には、私の機能login()after_login()が他のリクエストがスケジュールされ実行される前に呼び出されることを確認したいと思います。クッキーを使用したくないのは、長い間クロールを一時停止することができないからです。
start_requests()login()と呼ぶことができますが、これは最初にクローラを実行した場合にのみ機能します。

class MyCrawlSpider(CrawlSpider): 
    # ... 

    START_URLS = ['someurl.com', 'someurl2.com'] 
    LOGIN_PAGE = u'https://login_page.php' 

    def login(self): 
     return Request(url=self.LOGIN_PAGE, callback=self.login_email, 
         dont_filter=True, priority=9999)  

    def login_form(self, response): 
     return FormRequest.from_response(response, 
              formdata={'Email': 'myemail', 
                'Passwd': 'mypasswd'}, 
              callback=self.after_login, 
              dont_filter=True, 
              priority=9999) 

    def after_login(self, response): 
     if "authentication failed" in response.body: 
      self.logger.error("Login failed") 
      return 
     else: 
      print("Login Successful!!") 
      self.is_logged_in = True 
      for url in self.START_URLS: 
       yield Request(url, callback=self.parse_artists_json, dont_filter=True) 

Bottomline:私は以前の要求を再スケジュールする前に-s JOBDIR=...オプションを使用してクロールを再開したときに必ず呼び出される任意のコールバックはありますか?私はlogin()メソッドを呼び出すためにそれを使用します。

答えて

2

あなたはこの関数は、それはあなたがそこからRequestオブジェクトを生成するために期待していないので、クモ、その他の初期化のための資源配分を意図している(more here

spider_opened信号を使用することができます。

これは、保留中のリクエストの配列を持つことで回避できます。これは、scrapyでは手動でスケジュールされた要求を許可しないために必要です。

その後、あなたはキューの最初の要求としてログインキューに入れることができた後にクモを再開:あなたはまた、あなたのクモ

def next_request(self): 
    if self.requests: 
     yield self.requests.pop(0) 

そしてキューにnext_requestメソッドを追加する必要が

def spider_opened(self, spider): 
    self.spider.requests.insert(0, self.spider.login()) 

をすべてrequests配列に追加し、next_requestと呼び出して、それぞれの方法の最後を追加します。

def after_login(self, response): 
    if "authentication failed" in response.body: 
     self.logger.error("Login failed") 
     return 
    else: 
     print("Login Successful!!") 
     self.is_logged_in = True 
     if not self.requests: 
      for url in self.START_URLS: 
       self.requests.append(Request(url, callback=self.parse_artists_json, dont_filter=True) 

    yield self.next_request() 
+0

ありがとう、@ VMRuiz、私はまったく同じようなソリューションを持っていました。私はまだログインしていないことを確認し、ログインはスケジュールされていませんでしたし、私の解析メソッドでログイン要求がスケジュールされました。ソリューションはよりクリーンですが、以下の**問題は解決しません**:最初に解析メソッドが呼び出される瞬間に、スケジューラーは既にファイルから復元された要求のキューを持っています。 scrapyは非同期で動作するため、ログインを送信する前にいくつかの要求を送信します。 – Temak

+0

このシステムを使用すると、1つのリクエストのみをスケジュールすることができます。最悪のシナリオは、スケジューラーが最初に保留中の要求を処理してから、再度ログに記録することです。その場合、ログインのために要求が失敗したかどうかを確認し、再度キューに入れることができます。 – VMRuiz

関連する問題