我正在使用 Python Scrapy 工具从网站中提取数据。我正在使用 .php 从我的 php 代码中触发 Scrapy proc_open()。现在我需要维护一个仪表板之类的东西。在 Scrapy 中有没有办法获取 Crawler 详细信息,例如:
您的问题可以通过使用扩展来解决。
例如:
from datetime import datetime
from scrapy import signals
from twisted.internet.task import LoopingCall
class SpiderDetails(object):
"""Extension for collect spider information like start/stop time."""
update_interval = 5 # in seconds
def __init__(self, crawler):
# keep a reference to the crawler in case is needed to access to more information
self.crawler = crawler
# keep track of polling calls per spider
self.pollers = {}
@classmethod
def from_crawler(cls, crawler):
instance = cls(crawler)
crawler.signals.connect(instance.spider_opened, signal=signals.spider_opened)
crawler.signals.connect(instance.spider_closed, signal=signals.spider_closed)
return instance
def spider_opened(self, spider):
now = datetime.utcnow()
# store curent timestamp in db as 'start time' for this spider
# TODO: complete db calls
# start activity poller
poller = self.pollers[spider.name] = LoopingCall(self.spider_update, spider)
poller.start(self.update_interval)
def spider_closed(self, spider, reason):
# store curent timestamp in db as 'end time' for this spider
# TODO: complete db calls
# remove and stop activity poller
poller = self.pollers.pop(spider.name)
poller.stop()
def spider_update(self, spider):
now = datetime.utcnow()
# update 'last update time' for this spider
# TODO: complete db calls
pass
Run Code Online (Sandbox Code Playgroud)
Crawler 运行所需的时间:即end time - start time. 您可以在从 db 读取或存储以及结束时间时计算它。
爬虫的启动和停止时间:即存储在spider_opened和spider_closed方法中。
爬虫状态(活动或停止):如果now - last update time接近 5 秒,您的爬虫处于活动状态。否则,如果上次更新是很久以前(30 秒、5 分钟或更长时间),那么您的蜘蛛要么异常停止,要么挂断了。如果蜘蛛记录有一个,end time那么爬虫已经正确完成。
同时运行的爬虫列表:您的前端可以查询带有空的记录end time。那些蜘蛛要么跑,要么死了(以防那last update time是很久以前的事)。
考虑到spider_closed如果进程突然完成,将不会调用该信号。您将需要一个 cron 作业来清理和/或更新死记录。
不要忘记将扩展名添加到您的settings.py文件中,例如:
EXTENSIONS = {
# SpiderDetails class is in the file mybot/extensions.py
'mybot.extensions.SpiderDetails': 1000,
}
Run Code Online (Sandbox Code Playgroud)