5

個別のサイトへの HtmlXPathSelector リクエストを大量に作成する、scrapy を使用してスパイダーを作成しました。各要求が (非同期的に) 満たされると、.csv ファイルにデータの行が作成されます。データがまだ抽出されていない場合は要求が繰り返されるため、どの要求が最後に満たされたかを確認することはできません (データが数回失われる場合があります)。きれいなリストから始めても、データが抽出された直後に行が書き込まれるため、出力がごちゃごちゃしています。

ここで、1 つの列に基づいてそのリストを並べ替えたいと思いますが、すべての要求が完了した後です。「spider_closed」シグナルを使用して実際の関数をトリガーできますか? 以下のように、信号をディスパッチャーに接続してみましたが、この関数は、変数を操作したり、他の関数を呼び出したりするのではなく、出力するだけのようです。

def start_requests(self)
    ...  dispatcher.connect(self.spider_closed, signal=signals.engine_stopped) ....


def spider_closed(spider):
    print 'this gets printed alright'   # <-only if the next line is omitted...
    out = self.AnotherFunction(in)      # <-This doesn't seem to run
4

1 に答える 1

1

この問題を解決するためにパイプラインをハックしました。

ファイル: Project.middleware_module.SortedCSVPipeline

import csv
from scrapy import signals


class SortedCSVPipeline(object):

    def __init__(self):
        self.items = []
        self.file_name = r'YOUR_FILE_PATH_HERE'
        self.key = 'YOUR_KEY_HERE'

    @classmethod
    def from_crawler(cls, crawler):
        pipeline = cls()
        crawler.signals.connect(pipeline.spider_closed, signals.spider_closed)
        return pipeline

    def spider_closed(self, spider):
        for item in sorted(self.items, key=lambda k: k[self.key]):
            self.write_to_csv(item)

    def process_item(self, item, spider):
        self.items.append(item)
        return item

    def write_to_csv(self, item):
       writer = csv.writer(open(self.file_name, 'a'), lineterminator='\n')
       writer.writerow([item[key] for key in item.keys()])

ファイル: settings.py

ITEM_PIPELINES = {"Project.middleware_module.SortedCSVPipeline.SortedCSVPipeline" : 1000}

これを実行すると、このパイプラインが csv 書き込みを行うため、アイテム エクスポーターを使用する必要がなくなります。また、設定のパイプライン エントリの 1000 は、このパイプラインの前に実行する他のすべてのパイプラインよりも高い値である必要があります。プロジェクトでこれをテストしたところ、指定した列でソートされた csv ファイルが作成されました。HTH

乾杯

于 2015-06-23T19:19:46.133 に答える