3

我正在使用 Python Scrapy 工具从网站中提取数据。我从我的 php 代码中使用proc_open(). 现在我需要维护一个仪表板之类的东西。Scrapy 中有没有办法获取爬虫的详细信息,例如:

  1. Crawler 运行所花费的时间。
  2. 爬虫的启动和停止时间。
  3. 爬虫状态(活动或停止)。
  4. 同时运行的爬虫列表。
4

1 回答 1

6

您的问题可以通过使用扩展来解决。

例如:

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
  1. 爬虫运行所用的时间:即end time - start time。您可以在从 db 读取或存储以及结束时间时计算它。

  2. 爬虫的启动和停止时间:存储在spider_openedandspider_closed方法中。

  3. 爬虫状态(活动或停止):如果now - last update time接近 5 秒,您的爬虫处于活动状态。否则,如果上次更新是很久以前(30 秒,5 分钟或更长时间),那么您的蜘蛛程序要么异常停止,要么挂起。如果蜘蛛记录有end time则爬虫已正确完成。

  4. 同时运行的爬虫列表:你的前端可以查询空的记录end time。那些蜘蛛要么跑要么死(以防万一last update time很久以前)。

考虑到spider_closed如果过程突然结束,将不会调用信号。您将需要有一个 cron 作业来清理和/或更新死记录。

不要忘记将扩展名添加到您的settings.py文件中,例如:

EXTENSIONS = {
    # SpiderDetails class is in the file mybot/extensions.py
    'mybot.extensions.SpiderDetails': 1000,
}
于 2013-10-10T17:33:38.077 回答