如何使用 Nullhandler 重定向外部模块的记录器警告?

How to redirect logger warnings of external module with Nullhandler?

如果这个问题与 SO 上发布的其他问题相似,我深表歉意,但我已经尝试了很多给出的答案,但无法实现我想要做的事情。

我有一些调用外部模块的代码:

import trafilatura

# after obtaining article_html
text = trafilatura.extract(article_html, language=en)

这有时会在控制台上打印出警告,该警告来自 trafilatura 模块中的以下代码:

# at the top of the file
LOGGER = logging.getLogger(__name__)

# in the method that I'm calling
LOGGER.warning('HTML lang detection failed')

我不想将此消息和模块生成的其他消息直接打印到控制台,而是将它们存储在某个地方,以便我可以编辑消息并决定如何处理它们。 (具体来说,我想以稍微修改的形式保存消息,但仅在特定情况下。)我没有在自己的代码中使用日志记录库。

我尝试了以下解决建议:

buf = io.StringIO()
with contextlib.redirect_stderr(buf):  # I also tried redirect_stdout
    text = trafilatura.extract(article_html, language=en)

buf = io.StringIO()    
sysout = sys.stdout
syserr = sys.stderr
sys.stdout = sys.stderr = buf
text = trafilatura.extract(article_html, language=en)
sys.stdout = sysout
sys.stderr = syserr

然而,在这两种情况下,buf 仍然是空的,trafilatura 仍然将其日志消息打印到控制台。用其他调用(例如 print("test"))测试上面的重定向,它们似乎很好地捕捉到了这些,所以显然来自 trafilatura 的 LOGGER.warning() 只是没有打印到 stderr 或 stdout?

我以为我可以为 trafilatura 的 LOGGER 设置不同的输出流目标,但它使用的是 NullHandler,所以我既无法弄清楚它的流目标,也不知道如何更改它:

# from trafilatura's top-level __init__.py
logging.getLogger(__name__).addHandler(NullHandler())

有什么想法吗?提前致谢。

这里的想法是在 python 的标准日志记录库中工作。添加 NullHandler 实际上是添加记录器的库的标准推荐做法,因为如果不存在日志记录配置,它可以防止回退到 stderr。

这里可能发生的情况是,这些日志正在传播到根记录器,根记录器在其他地方附加了一些处理程序。您可以通过在代码中获取模块的记录器并将其设置为不传播来停止它:

# assuming that "trafilatura" is the __name__ of the module:
logger = logging.getLogger("trafilatura")
logger.propagate = False