Python scrapy:当爬行器退出时调用函数
有没有一种方法可以在Spider类终止之前触发该类中的方法 我可以自己终止蜘蛛,就像这样: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):
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
中,不推荐使用。相反,您可以使用frompydispatch 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。虽然还不能让它工作…在较新版本的scrapyscrapy.xlib中,pydispatch
已被弃用。除此之外,您可以在my scrapy中使用pydispatch导入调度程序中的,它是def close(self,reason):
,而不是closed
@AminahNuraini scrapy 1.0.4def 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