3

これが私がscrapyと呼ぶために使用しているPythonスクリプトです。

スクリプトからのScrapyクロールは、スクレイピング後のスクリプトの実行を常にブロックします

def stop_reactor():
    reactor.stop()
dispatcher.connect(stop_reactor, signal=signals.spider_closed)
spider = MySpider(start_url='abc')
crawler = Crawler(Settings())
crawler.configure()
crawler.crawl(spider)
crawler.start()
log.start()
log.msg('Running reactor...')
reactor.run()  # the script will block here until the spider is closed
log.msg('Reactor stopped.')

これが私のpipelines.pyコードです

from scrapy import log,signals
from scrapy.contrib.exporter import JsonItemExporter
from scrapy.xlib.pydispatch import dispatcher

class scrapermar11Pipeline(object):


    def __init__(self):
        self.files = {}
        dispatcher.connect(self.spider_opened , signals.spider_opened)
        dispatcher.connect(self.spider_closed , signals.spider_closed)


    def spider_opened(self,spider):
        file = open('links_pipelines.json' ,'wb')
        self.files[spider] = file
        self.exporter = JsonItemExporter(file)
        self.exporter.start_exporting()

    def spider_closed(self,spider):
       self.exporter.finish_exporting()
       file = self.files.pop(spider)
       file.close()

    def process_item(self, item, spider):
        self.exporter.export_item(item)
        log.msg('It reached here')
        return item

このコードはここから取得されます

Scrapy::JSONエクスポートに関する問題

このようにクローラーを実行すると

scrapy crawl MySpider -a start_url='abc'

期待される出力のリンクファイルが作成されます。しかし、Pythonスクリプトを実行すると、ダンプされたスクレイプ統計が前の実行と同様であるため、クローラーは実行されますが、ファイルは作成されません。最初のアプローチでファイルが作成されているため、Pythonスクリプトに誤りがあると思います。スクリプトでファイルを出力するにはどうすればよいですか?

4

2 に答える 2

1

このコードは私のために働いた:

from scrapy import signals, log
from scrapy.xlib.pydispatch import dispatcher
from scrapy.conf import settings
from scrapy.http import Request
from multiprocessing.queues import Queue
from scrapy.crawler import CrawlerProcess
from multiprocessing import Process
# import your spider here
def handleSpiderIdle(spider):
        reactor.stop()
mySettings = {'LOG_ENABLED': True, 'ITEM_PIPELINES': '<name of your project>.pipelines.scrapermar11Pipeline'} 

settings.overrides.update(mySettings)

crawlerProcess = CrawlerProcess(settings)
crawlerProcess.install()
crawlerProcess.configure()

spider = <nameofyourspider>(domain="") # create a spider ourselves
crawlerProcess.crawl(spider) # add it to spiders pool

dispatcher.connect(handleSpiderIdle, signals.spider_idle) # use this if you need to handle idle event (restart spider?)

log.start() # depends on LOG_ENABLED
print "Starting crawler."
crawlerProcess.start()
print "Crawler stopped."
于 2013-09-30T07:09:56.097 に答える
-1

私にとってうまくいった解決策は、実行スクリプトと内部 API の使用を捨て、代わりにコマンドラインと GNU Parallel を使用して並列化することでした。

コアごとに 1 つずつ、すべての既知のスパイダーを実行するには、次のようにします。

scrapy list | parallel --line-buffer scrapy crawl

scrapy listすべてのスパイダーを 1 行に 1 つずつリストします。代わりに、それらを引数としてパイプしてコマンド ( scrapy crawl) に追加し、GNU Parallel に渡すことができます。--line-bufferは、プロセスから返された出力が標準出力に混在して出力されることを意味しますが、4/2 行が一緒に文字化けするのではなく、行ごとに出力されます (他のオプションについては、 および を参照し--groupてください--ungroup)。

注: 明らかに、これは複数の CPU コアを持つマシンで最適に機能します。デフォルトでは、GNU Parallel はコアごとに 1 つのジョブを実行します。多くの最新の開発マシンとは異なり、安価な AWS EC2 および DigitalOcean 層には仮想 CPU コアが 1 つしかないことに注意してください。したがって、1 つのコアで同時にジョブを実行したい場合は、--jobsGNU Parallel の引数をいじる必要があります。たとえば、コアごとに 2 つの Scrapy クローラーを実行するには:

scrapy list | parallel --jobs 200% --line-buffer scrapy crawl
于 2015-04-03T00:23:54.320 に答える