Existe-t-il un moyen de déclencher une méthode dans une classe Spider juste avant sa fin?
Je peux terminer l'araignée moi-même, comme ceci:
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...
Mais je ne trouve aucune information sur la manière de déterminer le moment où l'araignée est sur le point de s'arrêter naturellement.
Il semble que vous puissiez enregistrer un auditeur de signal via dispatcher
.
Je voudrais essayer quelque chose comme:
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.
Juste pour mettre à jour, vous pouvez appeler closed
function comme ceci:
class MySpider(CrawlSpider):
def closed(self, reason):
do-something()
Pour Scrapy version 1.0.0+ (cela peut également fonctionner pour les anciennes versions).
from scrapy import signals
class MySpider(CrawlSpider):
name = 'myspider'
@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):
print('Opening {} spider'.format(spider.name))
def spider_closed(self, spider):
print('Closing {} spider'.format(spider.name))
Une bonne utilisation consiste à ajouter tqdm barre de progression à Spider 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
Pour moi l'acceptation n'a pas fonctionné/est obsolète au moins pour Scrapy 0.19 . Je l'ai obtenu pour fonctionner avec ce qui suit:
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
si vous avez beaucoup d'araignées et que vous voulez faire quelque chose avant la fermeture de chacune d'elles, il sera peut-être plus pratique d'ajouter statscollector dans votre projet.
dans les paramètres:
STATS_CLASS = 'scraper.stats.MyStatsCollector'
et collecteur:
from scrapy.statscollectors import StatsCollector
class MyStatsCollector(StatsCollector):
def _persist_stats(self, stats, spider):
do something here