信號(hào)(Signals)
記錄運(yùn)行時(shí)間主要用的的就是scrapy的singal信號(hào)管理违霞,點(diǎn)擊查看詳情
根據(jù)各種信號(hào)記錄數(shù)量和時(shí)間杈湾。
數(shù)據(jù)收集(Stats Collection)
Scrapy 提供了方便的收集數(shù)據(jù)的機(jī)制澳叉。數(shù)據(jù)以 key/value 方式存儲(chǔ),值大多是計(jì)數(shù)值相种。該機(jī)制叫做數(shù)據(jù)收集器(Stats Collector)塑猖,可以通過(guò) Crawler API 的屬性 stats來(lái)使用。
無(wú)論數(shù)據(jù)收集(stats collection)開(kāi)啟或者關(guān)閉擅编,數(shù)據(jù)收集器永遠(yuǎn)都是可用的攀细。因此可以 import 進(jìn)自己的模塊并使用其 API(增加值或者設(shè)置新的狀態(tài)鍵(stats keys))。該做法是為了簡(jiǎn)化數(shù)據(jù)收集的方法:不應(yīng)該使用超過(guò)一行代碼來(lái)收集你的 spider爱态,Scrapy 擴(kuò)展或者任何你使用數(shù)據(jù)收集器代碼里頭的狀態(tài)谭贪。
數(shù)據(jù)收集器的另一個(gè)特性是(在啟用狀態(tài)下)很高效,(在關(guān)閉情況下)非常高效(幾乎察覺(jué)不到)锦担。
數(shù)據(jù)收集器對(duì)每個(gè) spider 保持一個(gè)狀態(tài)俭识。當(dāng) spider 啟動(dòng)時(shí),該表自動(dòng)打開(kāi)洞渔,當(dāng) spider 關(guān)閉時(shí)套媚,自動(dòng)關(guān)閉缚态。
常見(jiàn)數(shù)據(jù)收集器使用方法:
通過(guò) stats 屬性來(lái)使用數(shù)據(jù)收集器。下面是在擴(kuò)展中使用的例子:
class ExtensionThatAccessStats(object):
def __init__(self, stats):
self.stats = stats
@classmethod
def from_crawler(cls, crawler):
return cls(crawler.stats)
#設(shè)置數(shù)據(jù):
stats.set_value('hostname', socket.gethostname())
#增加數(shù)據(jù)值:
stats.inc_value('pages_crawled')
#當(dāng)新的值比原來(lái)的值大時(shí)設(shè)置數(shù)據(jù):
stats.max_value('max_items_scraped', value)
#當(dāng)新的值比原來(lái)的值小時(shí)設(shè)置數(shù)據(jù):
stats.min_value('min_free_memory_percent', value)
#獲取數(shù)據(jù):
>>> stats.get_value('pages_crawled')
8
#獲取所有數(shù)據(jù):
>>> stats.get_stats()
{'pages_crawled': 1238, 'start_time': datetime.datetime(2009, 7, 14, 21, 47, 28, 977139)}
結(jié)合信號(hào)使用
import datetime
from scrapy import signals
class CoreStats(object):
def __init__(self, stats):
self.stats = stats
@classmethod
def from_crawler(cls, crawler):
o = cls(crawler.stats)
crawler.signals.connect(o.spider_opened, signal=signals.spider_opened)
crawler.signals.connect(o.spider_closed, signal=signals.spider_closed)
crawler.signals.connect(o.item_scraped, signal=signals.item_scraped)
crawler.signals.connect(o.item_dropped, signal=signals.item_dropped)
crawler.signals.connect(o.response_received, signal=signals.response_received)
return o
def spider_opened(self, spider):
self.stats.set_value('start_time', datetime.datetime.utcnow(), spider=spider)
def spider_closed(self, spider, reason):
self.stats.set_value('finish_time', datetime.datetime.utcnow(), spider=spider)
self.stats.set_value('finish_reason', reason, spider=spider)
def item_scraped(self, item, spider):
self.stats.inc_value('item_scraped_count', spider=spider)
def response_received(self, spider):
self.stats.inc_value('response_received_count', spider=spider)
def item_dropped(self, item, spider, exception):
reason = exception.__class__.__name__
self.stats.inc_value('item_dropped_count', spider=spider)
self.stats.inc_value('item_dropped_reasons_count/%s' % reason, spider=spider)