2

Scrapy を使用するかなり複雑なマルチプロセス プログラムがあります。それは約 95% の時間で完全に動作しますが、時折、DNSLookupError/TCPTimedOutError を引き起こす悪いサイトにヒットしたときに Twisted から未処理の例外が発生します。

これは問題にはなりませんが、残念ながら、これらのエラーにより、Scrapy は BaseSpider parse メソッドをスキップします。このメソッドでは、応答を処理するために Queue を設定しました。キューをスキップするため、スキップされた URL を特定する方法がありません。

すべての Scrapy リクエストがその解析メソッドで終了することを常に保証する方法はありますか? 必要なのは、これらの失敗した応答オブジェクトにアクセスしてキューに入れる方法だけです。

これが私のスパイダーコードの例です:

class SeerSpider(BaseSpider):
    """Scrapy-based html retrieval system."""

    name = "SeerSpider"

    def __init__(self, spider_queue, url_list):
        self.queue = spider_queue
        self.allowed_domains = []
        self.start_urls = []
        for url in url_list:
            self.allowed_domains.append(str(urlparse(url).netloc))
            self.start_urls.append(url)
        super(SeerSpider, self).__init__()

    def parse(self, response):
        """Extracts information from each website in start_urls."""
        self.queue.put(response)

ご覧のとおり、非常に基本的なものです。

その後、キューは次のように処理されます。

while True:
    response = spider_queue.get()
    ### DO STUFF HERE ###
    results_queue.put(result)

その後...

while True:
    try:
        result = results_queue.get(True, 60)
    except:
        print 'HALP', sys.exc_info()
        result = ['ERROR']
    self.results.append(result)
    counter -= 1
    if counter <= 0 or self.exit == True:
        for process in process_list:
            process.terminate()
        break

一時的な解決策としてキューのタイムアウトを追加したため、キューに存在しないアイテムを待機するときに無期限にハングすることはありません。ある種の応答オブジェクトが start_urls リストの各 URL のキューに入ることが保証できれば、すべての問題が解決します。

ありがとう

4

1 に答える 1

3

私はそれを理解しました、ミドルウェアは正しい道でしたが、それはスクレイピーミドルウェアではなくダウンローダーミドルウェアでした. process_exception メソッドを使用してダウンローダ ミドルウェアを実装した後、なんとか動作させることができました。

コードはここにあります:

class SpiderFailSignal(object):

    def process_exception(self, request, exception, spider):
        response = Response(request.url, status=666, body='error')
        spider.queue.put(response)
        return response

それから私は追加しました

settings.overrides['DOWNLOADER_MIDDLEWARES'] = {'seerspider.SpiderFailSignal': 901}

そしてそれはうまくいきました。

ただし、scrapy Spider_idle シグナルが発生するとキューにダミー値を追加し、そのアイテムに遭遇したらキューを終了する if ステートメントを作成しました。したがって、これらのソリューションの両方を一緒にすると、すべて修正されます。

于 2013-04-12T21:45:36.740 に答える