Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python scrapy:当爬行器退出时调用函数_Python_Scrapy - Fatal编程技术网

Python scrapy:当爬行器退出时调用函数

Python scrapy:当爬行器退出时调用函数,python,scrapy,Python,Scrapy,有没有一种方法可以在Spider类终止之前触发该类中的方法 我可以自己终止蜘蛛,就像这样: class MySpider(CrawlSpider): #Config stuff goes here... def quit(self): #Do some stuff... raise CloseSpider('MySpider is quitting now.') def my_parser(self, response):

有没有一种方法可以在Spider类终止之前触发该类中的方法

我可以自己终止蜘蛛,就像这样:

class MySpider(CrawlSpider):
    #Config stuff goes here...

    def quit(self):
        #Do some stuff...
        raise CloseSpider('MySpider is quitting now.')

    def my_parser(self, response):
        if termination_condition:
            self.quit()

        #Parsing stuff goes here...

但是我找不到关于如何确定爬行器何时将自然退出的任何信息。

看起来您可以通过
dispatcher
注册信号侦听器

我想尝试一下:

from scrapy import signals
from scrapy.xlib.pydispatch import dispatcher

class MySpider(CrawlSpider):
    def __init__(self):
        dispatcher.connect(self.spider_closed, signals.spider_closed)

    def spider_closed(self, spider):
      # second param is instance of spder about to be closed.


在较新版本的scrapy
scrapy.xlib.pydispatch
中,不推荐使用。相反,您可以使用from
pydispatch import dispatcher

对我来说,接受的不起作用/至少对于scrapy 0.19来说已经过时。 不过,我让它与以下内容一起工作:

from scrapy.signalmanager import SignalManager
from scrapy.xlib.pydispatch import dispatcher

class MySpider(CrawlSpider):
    def __init__(self, *args, **kwargs):
        super(MySpider, self).__init__(*args, **kwargs)
        SignalManager(dispatcher.Any).connect(
            self.closed_handler, signal=signals.spider_closed)

    def closed_handler(self, spider):
        # do stuff here

要进行更新,您可以如下调用函数:

class MySpider(CrawlSpider):
    def closed(self, reason):
        do-something()

对于Scrapy版本1.0.0+(也适用于旧版本)

一个很好的用法是向scrapy spider添加进度条

# -*- coding: utf-8 -*-
from scrapy import signals
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from tqdm import tqdm


class MySpider(CrawlSpider):
    name = 'myspider'
    allowed_domains = ['somedomain.comm']
    start_urls = ['http://www.somedomain.comm/ccid.php']

    rules = (
        Rule(LinkExtractor(allow=r'^http://www.somedomain.comm/ccds.php\?id=.*'),
             callback='parse_item',
             ),
        Rule(LinkExtractor(allow=r'^http://www.somedomain.comm/ccid.php$',
                           restrict_xpaths='//table/tr[contains(., "SMTH")]'), follow=True),
    )

    def parse_item(self, response):
        self.pbar.update()  # update progress bar by 1
        item = MyItem()
        # parse response
        return item

    @classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        spider = super(MySpider, cls).from_crawler(crawler, *args, **kwargs)
        crawler.signals.connect(spider.spider_opened, signals.spider_opened)
        crawler.signals.connect(spider.spider_closed, signals.spider_closed)
        return spider

    def spider_opened(self, spider):
        self.pbar = tqdm()  # initialize progress bar
        self.pbar.clear()
        self.pbar.write('Opening {} spider'.format(spider.name))

    def spider_closed(self, spider):
        self.pbar.clear()
        self.pbar.write('Closing {} spider'.format(spider.name))
        self.pbar.close()  # close progress bar

如果您有许多spider,并且希望在每个spider关闭之前做一些事情,那么在您的项目中添加StatCollector可能会比较方便

在设置中:

STATS_CLASS = 'scraper.stats.MyStatsCollector'
和收集器:

from scrapy.statscollectors import StatsCollector

class MyStatsCollector(StatsCollector):
    def _persist_stats(self, stats, spider):
        do something here
对于最新版本(v1.7),只需在spider类中定义
closed(reason)
方法

关闭(原因)

蜘蛛关闭时调用。此方法提供了一个快捷方式 signals.connect()用于十字轴闭合信号


工作正常。但我建议将方法命名为MySpider.quit()或类似名称,以避免与信号名称混淆。谢谢很好的解决方案。是的,对于
爬行爬行器
,这个例子应该完全一样。我不明白为什么爬行器的第二个参数是必需的。蜘蛛不是自己封闭的吗?不适合v。1.1因为xlib.pydispatch已被弃用。相反,他们建议使用PyDispatcher。虽然还不能让它工作…在较新版本的scrapy
scrapy.xlib中,pydispatch
已被弃用。除此之外,您可以在my scrapy中使用pydispatch导入调度程序中的
,它是
def close(self,reason):
,而不是
closed
@AminahNuraini scrapy 1.0.4
def closed(reason)
这是新方法!虽然它看起来不那么透明,但它的优点是消除了使用:
def\uuuu init\uuuuu(self):…
和从scrapy.xlib.pydispatch import dispatcher导入
的PyDispatcher所带来的额外混乱。
from scrapy.statscollectors import StatsCollector

class MyStatsCollector(StatsCollector):
    def _persist_stats(self, stats, spider):
        do something here