2017-08-02 19 views
1

これはウェブサイトを介してクロールするスパイダーが1つあり、製品情報を一掃しています...そして、リンクは最初に構築され、それをチェック目的のために使用します。Scrapyはスパイダーがもう1つのプロパティを組み込んだものを持っています

私はこれをすべて1つのスパイダーで行うことができますが、スパイダーはすでに非常に大きい(25以上の異なるドメインの一般的なスパイダーです)、可能な限り分離しておきたいと思います。現在、私のようなこのマスタークモのインスタンスを作成しています次の次に見られるよう

def run_spiders(*urls, ajax=False): 
    process = CrawlerProcess(get_project_settings()) 
    for url in urls: 
     process.crawl(MasterSpider, start_page = url, ajax_rendered = ajax) 
    process.start() 

を理想的には、これがどのように動作するかのようなものです:

私はMasterSpiderのclosed_handler内で別のクローラープロセスを生成しようとしましたが、リアクターはすでに非常に明確に実行されていますそれはうまくいきません。何か案は?

私がクローラーランナーに切り替えるときはいつでも、正確にここにあるドキュメンテーション/質問にあるものであっても、正確には動作しません。私はfrom_crawlerを使用して行くことが私の方法かもしれないと思っていますが、私は完全にはわかりません。

答えて

0

スクリプトで複数のクローラを連鎖させるには、Twisted deferredにダイビングする必要があります。潜在的な解決策としてOfficial docs have this。それは少し長いとハックだが、それはそれは見た目ほど複雑ではないのです

from twisted.internet import reactor, defer 
import scrapy 
from scrapy.crawler import CrawlerRunner 
from scrapy.utils.log import configure_logging 
from scrapy import signals 

DATA = [] 

def store_item(*args, **kwargs): 
    DATA.append(kwargs['item']) 


class ProducerSpider(scrapy.Spider): 
    name = 'spider1' 
    start_urls = ['http://stackoverflow.com'] 

    def parse(self, response): 
     yield {'url': response.url} 


class ConsumerSpider(scrapy.Spider): 
    name = 'spider2' 

    def start_requests(self): 
     for item in DATA: 
      yield scrapy.Request(item['url']) 

    def parse(self, response): 
     yield {'url': response.url} 


configure_logging() 
runner = CrawlerRunner() 


@defer.inlineCallbacks 
def crawl(): 
    crawler1 = runner.create_crawler(ProducerSpider) 
    crawler2 = runner.create_crawler(ConsumerSpider) 
    crawler1.signals.connect(store_item, signals.item_scraped) 
    crawler2.signals.connect(store_item, signals.item_scraped) 
    yield runner.crawl(crawler1) 
    yield runner.crawl(crawler2) 
    reactor.stop() 


crawl() 
reactor.run() # the script will block here until the last crawl call is finished 
print('TOTAL RESULTS:') 
print(DATA) 

そのコードスニペットによると、私たちはこのようなものを作成することができます

  1. は2つのクモのクラスを作成し、 を作成してクロールを管理する。
  2. 各スパイダーのクローラーを作成し、それらをランナーに連結します。
  3. 私たちの共有変数DATA

に自分のアイテムを保存するために、これらの我々の2つのクローラに信号を追加しますので、最初のクローラーがクロールし、ちょうどDATAに追加しstore_item機能を通じて、すべてのアイテムを置きます。次に、2番目のクローラが起動し、start_requestsのメソッドがDATAから直接読み取られ、開始点が生成されます。

関連する問題