代码之家  ›  专栏  ›  技术社区  ›  D-Kalck

如何从另一只蜘蛛开始抓起一只痒痒的蜘蛛

  •  3
  • D-Kalck  · 技术社区  · 9 年前

    我有两个蜘蛛在一个肮脏的项目。Spider1爬行页面列表或整个网站,并分析内容。Spider2使用Splash在谷歌上获取URL,并将该列表传递给Spider1。

    # 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,它“起作用”,但仍然有错误消息。在解析方法中使用爬行器时,它不起作用。

    1 回复  |  直到 9 年前
        1
  •  3
  •   Mikhail Korobov    9 年前

    scrapy crawl 命令(请参见 https://github.com/scrapy/scrapy/issues/1226 ). 如果您自己编写启动脚本,则可以从爬行器启动爬行器-诀窍是使用相同的CrawlerProcess/CrawlerRunner实例。

    一种更简单的方法是重写代码以使用单个Spider类,或者创建一个运行的脚本(bash、Makefile、luigi/aiffort,如果您想喜欢的话) scrapy crawl spider1 -o items.jl scrapy crawl spider2 ; 第二个蜘蛛可以读取第一个蜘蛛创建的项目并生成 start_requests 照着