Scrapy - 使用蜘蛛名称同时记录到文件和标准输出

时间:2011-12-16 09:37:41

标签: python web-crawler scrapy

我决定使用Python日志记录模块,因为Twisted on std error生成的消息太长了,我希望INFO级别有意义的消息,例如StatsCollector生成的消息在保持屏幕消息的同时写在单独的日志文件上。

 from twisted.python import log
     import logging
     logging.basicConfig(level=logging.INFO, filemode='w', filename='buyerlog.txt')
     observer = log.PythonLoggingObserver()
     observer.start()

嗯,这很好,我收到了我的消息,但缺点是我不知道消息是由哪个蜘蛛生成的!这是我的日志文件,%(name)s显示“twisted”:

 INFO:twisted:Log opened.
  2 INFO:twisted:Scrapy 0.12.0.2543 started (bot: property)
  3 INFO:twisted:scrapy.telnet.TelnetConsole starting on 6023
  4 INFO:twisted:scrapy.webservice.WebService starting on 6080
  5 INFO:twisted:Spider opened
  6 INFO:twisted:Spider opened
  7 INFO:twisted:Received SIGINT, shutting down gracefully. Send again to force unclean shutdown
  8 INFO:twisted:Closing spider (shutdown)
  9 INFO:twisted:Closing spider (shutdown)
 10 INFO:twisted:Dumping spider stats:
 11 {'downloader/exception_count': 3,
 12  'downloader/exception_type_count/scrapy.exceptions.IgnoreRequest': 3,
 13  'downloader/request_bytes': 9973,

与标准错误上的扭曲产生的消息相比:

2011-12-16 17:34:56+0800 [expats] DEBUG: number of rules: 4
2011-12-16 17:34:56+0800 [scrapy] DEBUG: Telnet console listening on 0.0.0.0:6023
2011-12-16 17:34:56+0800 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080
2011-12-16 17:34:56+0800 [iproperty] INFO: Spider opened
2011-12-16 17:34:56+0800 [iproperty] DEBUG: Redirecting (301) to <GET http://www.iproperty.com.sg/> from <GET http://iproperty.com.sg>
2011-12-16 17:34:57+0800 [iproperty] DEBUG: Crawled (200) <

我已尝试过%(name)s,%(module)s等,但我似乎无法显示蜘蛛名称。有谁知道答案?

编辑: 在设置中使用LOG_FILELOG_LEVEL的问题是,在std错误中不会显示较低级别的消息。

7 个答案:

答案 0 :(得分:23)

您想使用ScrapyFileLogObserver

import logging
from scrapy.log import ScrapyFileLogObserver

logfile = open('testlog.log', 'w')
log_observer = ScrapyFileLogObserver(logfile, level=logging.DEBUG)
log_observer.start()

我很高兴你问这个问题,我一直想自己做这件事。

答案 1 :(得分:15)

使用以下方法重定向输出非常简单:scrapy some-scrapy's-args 2>&1 | tee -a logname

这样,所有scrapy输入stdout和stderr的内容都将被重定向到一个logname文件,并且也会被引导到屏幕上。

答案 2 :(得分:7)

对于在阅读当前documentation版本之前来到这里的所有人:

%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only
%~dp$PATH:I - searches the directories listed in the PATH
               environment variable for %I and expands to the
               drive letter and path of the first one found.
%~ftzaI     - expands %I to a DIR like output line

答案 3 :(得分:5)

我知道这是旧的,但这是一个非常有用的帖子,因为该课程仍未在Scrapy文档中正确记录。此外,我们可以跳过导入日志记录并直接使用scrapy日志。谢谢大家!

from scrapy import log

logfile = open('testlog.log', 'a')
log_observer = log.ScrapyFileLogObserver(logfile, level=log.DEBUG)
log_observer.start()

答案 4 :(得分:0)

如Scrapy官方文档所述:

  

Scrapy使用Python的内置日志记录系统进行事件记录。

因此,您可以像普通的Python脚本一样配置记录器。

首先,您必须导入日志记录模块:

import logging

您可以将此行添加到蜘蛛:

logging.getLogger().addHandler(logging.StreamHandler())

它添加了流处理程序以登录到控制台。

在那之后,您必须配置日志文件路径。

添加一个名为custom_settings的字典,其中包含您的蜘蛛指定设置:

custom_settings = {
     'LOG_FILE': 'my_log.log',
     'LOG_LEVEL': 'INFO',
     ... # you can add more settings
 }

整个类如下:

import logging

class AbcSpider(scrapy.Spider):
    name: str = 'abc_spider'
    start_urls = ['you_url']
    custom_settings = {
         'LOG_FILE': 'my_log.log',
         'LOG_LEVEL': 'INFO',
         ... # you can add more settings
     }
     logging.getLogger().addHandler(logging.StreamHandler())

     def parse(self, response):
        pass

答案 5 :(得分:0)

不再支持ScrapyFileLogObserver。您可以使用标准的python日志记录模块。

import logging
logging.getLogger().addHandler(logging.StreamHandler())

答案 6 :(得分:0)

从Scrapy 2.3开始,上面提到的所有答案都不适合我。 此外,在documentation中找到的解决方案会导致每条消息覆盖日志文件,这当然不是您想要的日志。 我找不到将模式更改为“ a”(附加)的内置设置。 我使用以下配置代码同时记录到文件和标准输出:

configure_logging(settings={
    "LOG_STDOUT": True
})
file_handler = logging.FileHandler(filename, mode="a")
formatter = logging.Formatter(
    fmt="%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s",
    datefmt="%H:%M:%S"
)
file_handler.setFormatter(formatter)
file_handler.setLevel("DEBUG")
logging.root.addHandler(file_handler)