【问题标题】:Scrapy - logging to file and stdout simultaneously, with spider namesScrapy - 使用蜘蛛名称同时记录到文件和标准输出
【发布时间】:2011-12-16 09:37:41
【问题描述】:

我决定使用 Python 日志记录模块,因为 Twisted 在 std 错误上生成的消息太长,我想将 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 错误中不会显示较低级别的消息。

【问题讨论】:

  • 你把你的代码放在哪里了? setting.py 还是蜘蛛代码?

标签: python web-crawler scrapy


【解决方案1】:

您想使用ScrapyFileLogObserver

import logging
from scrapy.log import ScrapyFileLogObserver

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

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

【讨论】:

  • 在我的 settings.py 中添加这些行后,scrapy 无法找到我的蜘蛛。 (命令行)
  • 嗯,我把它放在我的蜘蛛模块中,它工作得很好..让我试验一下。 编辑: 把它放在你的蜘蛛模块的__init__ 文件中怎么样?这似乎可以完成这项工作。
  • 嗯,把它放在蜘蛛的工作中。有趣的是为什么它在 settings.py 中不起作用。另外,我在文档中的任何地方都找不到这个 ScrapyFileObserver。也许你可以引导我到链接(除了 github)?
  • 这似乎不是一个记录的功能。必须查看scrapy.log 的来源才能找到它。
  • 截至 2017 年,此模块已被删除,现在已弃用:“模块 scrapy.log 已弃用,Scrapy 现在依赖内置 Python 库进行日志记录。阅读更新的日志记录条目文档以了解更多信息。”
【解决方案2】:

很容易重定向输出使用:scrapy some-scrapy's-args 2&gt;&amp;1 | tee -a logname

这样,scrapy 输出到 stdout 和 stderr 的所有内容都将被重定向到一个 logname 文件,并打印到屏幕上。

【讨论】:

  • 完美运行!它非常适合开发,当我们只是在尝试使用爬虫并且日志太长而无法保留在终端中时,但我们还不想在蜘蛛中编写整个 python 日志记录。
  • 终于找到了适合我的解决方案。不幸的是,我猜它保存了一些编码错误的日志。 ^[[0;0;34m2019-05-07 17:09:34^[[0;0m ^[[0;0;36m[scrapy.extensions.telnet]^[[0;0m ^[[0;0 ;31mINFO^[[0;0m:
【解决方案3】:

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

import logging
from scrapy.utils.log import configure_logging

configure_logging(install_root_handler=False)
logging.basicConfig(
    filename='log.txt',
    filemode = 'a',
    format='%(levelname)s: %(message)s',
    level=logging.DEBUG
)

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      正如 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
      

      【讨论】:

      • 您似乎还没有将自定义设置添加到记录器中。对吗?
      • 这对我有帮助,但前两位就是所需要的:导入日志记录并添加处理程序。您不一定需要custom_settings。我将导入和处理程序放在settings.py 而不是蜘蛛中。
      【解决方案6】:

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

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

      【讨论】:

      • 你可以在settings.py模块中做到这一点,例如
      【解决方案7】:

      从 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) 
      

      【讨论】:

      • 这是一个了不起的解决方案。我很难用 print() 创建一个日志文件。非常感谢。
      猜你喜欢
      • 1970-01-01
      • 2012-02-16
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-20
      • 2012-03-15
      • 2013-01-13
      相关资源
      最近更新 更多