2017-07-25 110 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在一个单一的蜘蛛是完全支持(它应该只是工作),你不必为他们创建单独的蜘蛛。