2017-07-25 114 views
2

我在一個Scrapy項目中有兩個蜘蛛。 Spider1抓取頁面或整個網站的列表並分析內容。 Spider2使用Splash在Google上獲取網址並將該列表傳遞給Spider1。如何從另一個開始Scrapy蜘蛛

所以,Spider1抓取和分析內容,並可以在不被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 
     ''' 

爲Spider2

# 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我有這樣的錯誤:twisted.internet.error.ReactorAlreadyRunning和Spider1是在沒有URL列表的情況下調用。 我嘗試使用Scrapy文檔建議的CrawlRunner,但它是同樣的問題。 我嘗試使用CrawlProcess裏面的解析方法,它「工作」,但是,我仍然有錯誤消息。在解析方法中使用CrawlRunner時,它不起作用。

+0

我不知道,但我認爲蜘蛛必須在兩個不同的文件 –

+0

他們在分開的文件。 –

回答

1

如果您使用scrapy crawl命令(請參閱https://github.com/scrapy/scrapy/issues/1226),目前無法從其他蜘蛛啓動蜘蛛。如果您自己編寫啓動腳本,則可以從蜘蛛啓動蜘蛛 - 訣竅是使用相同的CrawlerProcess/CrawlerRunner實例。

雖然我不想那麼做,但是你正在爲框架而戰。支持這個用例會很好,但現在還沒有真正支持。

更簡單的方法是重寫您的代碼以使用單個Spider類,或者創建一個腳本(bash,Makefile,luigi/airflow,如果您想要看起來),它運行scrapy crawl spider1 -o items.jl,然後是scrapy crawl spider2;第二隻蜘蛛可以讀取由第一隻蜘蛛創建的物品並據此生成start_requests

FTR:結合SplashRequests和普通scrapy.Requests在一個單一的蜘蛛是完全支持(它應該只是工作),你不必爲他們創建單獨的蜘蛛。