2017-07-25 20 views
2

私は1つのScrapyプロジェクトで2つのスパイダーを持っています。 Spider1は、ページまたはWebサイト全体のリストをクロールし、その内容を分析します。 Spider2はSplashを使用してGoogleでURLを取得し、そのリストをSpider1に渡します。 twisted.internet.error.ReactorAlreadyRunningをしてSpider1がある:別のものからScrapyスパイダーを始める方法

ので、Spider1は、コンテンツを分析し、Spider2を実行しているとき、私はこのエラーを持っているSpider2

# coding: utf8 
from scrapy.spiders import CrawlSpider 
import scrapy 


class Spider1(scrapy.Spider): 
    name = "spider1" 
    tokens = [] 
    query = '' 

    def __init__(self, *args, **kwargs): 
     ''' 
     This spider works with two modes, 
     if only one URL it crawls the entire website, 
     if a list of URLs only analyze the page 
     ''' 
     super(Spider1, self).__init__(*args, **kwargs) 
     start_url = kwargs.get('start_url') or '' 
     start_urls = kwargs.get('start_urls') or [] 
     query = kwargs.get('q') or '' 
     if google_query != '': 
      self.query = query 
     if start_url != '': 
      self.start_urls = [start_url] 
     if len(start_urls) > 0: 
      self.start_urls = start_urls 


    def parse(self, response): 
     ''' 
     Analyze and store data 
     ''' 
     if len(self.start_urls) == 1: 
      for next_page in response.css('a::attr("href")'): 
       yield response.follow(next_page, self.parse) 

    def closed(self, reason): 
     ''' 
     Finalize crawl 
     ''' 

# coding: utf8 
import scrapy 
from scrapy_splash import SplashRequest 
from scrapy.crawler import CrawlerProcess 
from scrapy.utils.project import get_project_settings 


class Spider2(scrapy.Spider): 
    name = "spider2" 
    urls = [] 
    page = 0 

    def __init__(self, *args, **kwargs): 
     super(Spider2, self).__init__(*args, **kwargs) 
     self.query = kwargs.get('q') 
     self.url = kwargs.get('url') 
     self.start_urls = ['https://www.google.com/search?q=' + self.query] 

    def start_requests(self): 
     splash_args = { 
      'wait:': 2, 
     } 
     for url in self.start_urls: 
      splash_args = { 
       'wait:': 1, 
      } 
      yield SplashRequest(url, self.parse, args=splash_args) 

    def parse(self, response): 
     ''' 
     Extract URLs to self.urls 
     ''' 
     self.page += 1 

    def closed(self, reason): 
     process = CrawlerProcess(get_project_settings()) 
     for url in self.urls: 
      print(url) 
     if len(self.urls) > 0: 
      process.crawl('lexi', start_urls=self.urls, q=self.query) 
      process.start(False) 

Spider2

のコードによって呼び出されることなく使用することができクロールし、 URLのリストなしで呼び出されます。 CrawlRunnerをScrapyのマニュアルでアドバイスしてみましたが、同じ問題です。 パーズメソッド内でCrawlProcessを使用しようとしましたが、「機能する」が、まだエラーメッセージが表示されます。解析メソッドの内部でCrawlRunnerを使用すると、動作しません。

+0

私は確信していますが、私はスパイダーが2つの異なるファイルに存在しなければならないと思います。 –

+0

これらは分離されたファイルです。 –

答えて

1

現在、scrapy crawlコマンド(https://github.com/scrapy/scrapy/issues/1226を参照)を使用している場合、他のスパイダーからスパイダーを開始することはできません。スタートアップスクリプトを自分で作成する場合は、スパイダーからスパイダーを起動することができます。トリックは同じCrawlerProcess/CrawlerRunnerインスタンスを使用することです。

私はそれをやっていませんが、あなたはフレームワークと戦っています。このユースケースをサポートすることはうれしいことですが、実際は今サポートされていません。

簡単な方法は、単一のSpiderクラスを使用するようにコードを書き直すか、scrapy crawl spider1 -o items.jlとそれに続くscrapy crawl spider2を実行するスクリプト(bash、Makefile、luigi/airflowをファンシーにしたい)を作成することです。第2のスパイダーは第1のスパイダーによって作成されたアイテムを読み取り、それに応じてstart_requestsを生成することができます。

FTR:1つのスパイダーでSplashRequestsと通常のscrapy.Requestsを組み合わせることは完全にサポートされています(これはうまくいくはずです)、別のスパイダーを作成する必要はありません。

関連する問題