Python Scrapy框架-着色日志

Python Scrapy框架-着色日志,python,logging,colors,scrapy,Python,Logging,Colors,Scrapy,我正试图使刮擦输出彩色日志。我不太熟悉Python日志记录,但我的理解是,我必须制作自己的格式化程序,并让Scrapy使用它。我成功地使用Clint制作了一个格式化程序来着色输出 我的问题是我不能使它在Scrapy范围内正确工作。我希望我的spider中的logger对象有一个处理程序,然后我会切换该处理程序的格式化程序。当我查看spider.logger.logger中的内容时,我发现handler是一个空列表。我试图在一个新的流处理程序中添加我的格式化程序 crawler.spider.lo

我正试图使刮擦输出彩色日志。我不太熟悉Python日志记录,但我的理解是,我必须制作自己的格式化程序,并让Scrapy使用它。我成功地使用Clint制作了一个格式化程序来着色输出

我的问题是我不能使它在Scrapy范围内正确工作。我希望我的spider中的logger对象有一个处理程序,然后我会切换该处理程序的格式化程序。当我查看
spider.logger.logger
中的内容时,我发现
handler
是一个空列表。我试图在一个新的流处理程序中添加我的格式化程序

crawler.spider.logger.logger.addHandler(sh)
其中sh是使用我的颜色格式化程序的处理程序

这增加了一个效果,使每个消息输出两次。第一条消息是彩色的,但没有粗糙的格式。第二个是没有颜色的粗糙格式

如何使Scrapy输出彩色日志保持与在
settings.py中设置的格式相同

import scrapy.utils.log

_get_handler = copy.copy(scrapy.utils.log._get_handler)


def _get_handler_custom(*args, **kwargs):
    handler = _get_handler(*args, **kwargs)
    handler.setFormatter(your_custom_formatter)
    return handler

scrapy.utils.log._get_handler = _get_handler_custom
import copy

from colorlog import ColoredFormatter
import scrapy.utils.log

color_formatter = ColoredFormatter(
    (
        '%(log_color)s%(levelname)-5s%(reset)s '
        '%(yellow)s[%(asctime)s]%(reset)s'
        '%(white)s %(name)s %(funcName)s %(bold_purple)s:%(lineno)d%(reset)s '
        '%(log_color)s%(message)s%(reset)s'
    ),
    datefmt='%y-%m-%d %H:%M:%S',
    log_colors={
        'DEBUG': 'blue',
        'INFO': 'bold_cyan',
        'WARNING': 'red',
        'ERROR': 'bg_bold_red',
        'CRITICAL': 'red,bg_white',
    }
)

_get_handler = copy.copy(scrapy.utils.log._get_handler)

def _get_handler_custom(*args, **kwargs):
    handler = _get_handler(*args, **kwargs)
    handler.setFormatter(color_formatter)
    return handler

scrapy.utils.log._get_handler = _get_handler_custom
谢谢

如果您只想着色,您可以使用ANSI转义码在
settings.py
中进行自定义

例如:

LOG_FORMAT = '\x1b[0;0;34m%(asctime)s\x1b[0;0m \x1b[0;0;36m[%(name)s]\x1b[0;0m \x1b[0;0;31m%(levelname)s\x1b[0;0m: %(message)s'
如果您还想用不同的颜色为不同的日志级别着色,可以覆盖
scrapy.utils.log.\u get\u handler
()

将其放在
设置.py的顶部附近

import scrapy.utils.log

_get_handler = copy.copy(scrapy.utils.log._get_handler)


def _get_handler_custom(*args, **kwargs):
    handler = _get_handler(*args, **kwargs)
    handler.setFormatter(your_custom_formatter)
    return handler

scrapy.utils.log._get_handler = _get_handler_custom
import copy

from colorlog import ColoredFormatter
import scrapy.utils.log

color_formatter = ColoredFormatter(
    (
        '%(log_color)s%(levelname)-5s%(reset)s '
        '%(yellow)s[%(asctime)s]%(reset)s'
        '%(white)s %(name)s %(funcName)s %(bold_purple)s:%(lineno)d%(reset)s '
        '%(log_color)s%(message)s%(reset)s'
    ),
    datefmt='%y-%m-%d %H:%M:%S',
    log_colors={
        'DEBUG': 'blue',
        'INFO': 'bold_cyan',
        'WARNING': 'red',
        'ERROR': 'bg_bold_red',
        'CRITICAL': 'red,bg_white',
    }
)

_get_handler = copy.copy(scrapy.utils.log._get_handler)

def _get_handler_custom(*args, **kwargs):
    handler = _get_handler(*args, **kwargs)
    handler.setFormatter(color_formatter)
    return handler

scrapy.utils.log._get_handler = _get_handler_custom
它所做的是在调用原始的
\u get\u处理程序后重置格式化程序,然后将其重新附加到
scrapy.utils.log
。 这是一个黑客解决方案,可能不是最佳实践,但它确实有效

实现这一点的更合适的方法是重写
logging.StreamHandler
。有一个可以引导你走向正确方向的答案

这里我提供了我在项目中使用的完整工作代码(正在使用第三方软件包)

settings.py

import scrapy.utils.log

_get_handler = copy.copy(scrapy.utils.log._get_handler)


def _get_handler_custom(*args, **kwargs):
    handler = _get_handler(*args, **kwargs)
    handler.setFormatter(your_custom_formatter)
    return handler

scrapy.utils.log._get_handler = _get_handler_custom
import copy

from colorlog import ColoredFormatter
import scrapy.utils.log

color_formatter = ColoredFormatter(
    (
        '%(log_color)s%(levelname)-5s%(reset)s '
        '%(yellow)s[%(asctime)s]%(reset)s'
        '%(white)s %(name)s %(funcName)s %(bold_purple)s:%(lineno)d%(reset)s '
        '%(log_color)s%(message)s%(reset)s'
    ),
    datefmt='%y-%m-%d %H:%M:%S',
    log_colors={
        'DEBUG': 'blue',
        'INFO': 'bold_cyan',
        'WARNING': 'red',
        'ERROR': 'bg_bold_red',
        'CRITICAL': 'red,bg_white',
    }
)

_get_handler = copy.copy(scrapy.utils.log._get_handler)

def _get_handler_custom(*args, **kwargs):
    handler = _get_handler(*args, **kwargs)
    handler.setFormatter(color_formatter)
    return handler

scrapy.utils.log._get_handler = _get_handler_custom

我知道我们不该说谢谢,但是谢谢!很好的回答:这很好,我刚刚将其编码到我的项目中,老实说,它似乎应该在默认情况下随Scrapy一起发布,也许github上的pull请求/Scrapy贡献是合适的?