Trafilatura 2.0 的 extract() 函数无论如何设置都会丢掉 <h2> 的解决方案
Trafilatura用起来很顺手,但是extract() 函数无论如何设置都会丢弃正常的 <h2> 标签。
Python 3.12.3 (main, Apr 10 2024, 05:33:47) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> #!/usr/bin/env python3
>>> import trafilatura
>>> from trafilatura.settings import use_config
>>>
>>> html = '''
... <body> <!-- 只加这一行 -->
... <h2>Understanding Git Undo Mechanisms</h2>
... <p>In software development, erroneous code commits are common occurrences.</p>
... <h2>Basic Undo Operations: git reset</h2>
... <p>git reset is the most commonly used undo command.</p>
... </body> <!-- 和这一行 -->
... '''
>>>
>>> cfg = use_config()
>>> cfg.set('DEFAULT', 'EXTRACTION_STRICT', '0') # 依然关严格模式
>>>
>>> txt = trafilatura.extract(
... html,
... output_format='txt',
... config=cfg,
... favor_recall=True,
... include_formatting=True,
... favor_precision=False)
>>>
>>> print(repr(txt))
'In software development, erroneous code commits are common occurrences.\ngit reset is the most commonly used undo command.'
>>> print('含第一个h2:', 'Understanding Git Undo Mechanisms' in txt)
含第一个h2: False
>>> print('含第二个h2:', 'Basic Undo Operations: git reset' in txt)
含第二个h2: False
>>> 感觉无解呀,为何这么好用的工具,会有这种问题……
jerkzhang
使用多个AI进行Debug了几百轮,最终基于AI没有找到解决方案。
后续通过阅读Github的问题列表的讨论,找到了根源。
Trafilatura并不是类似bs的这种提取,它的提取是对网页的整体分析,来进行提取,背后是有相应的算法,从而准确提取;上述你测试的这些,并非是完整的HTML页面的源码,所以提权下来,基于其算法,所以把h2省略掉了,这不是BUG,而是Trafilatura自身的特性。
因此,你可以试着把你要提取的内容,尽量组成一个相对完整的页面。比如:
html_blog = f"<header><h1>{title}</h1></header><article>{article_content}</article>"形成上述结构,就可以提取到正文部分的h2标题了。
下面,我们展示一个完整的例子,这样就能把h2提取到了。
import trafilatura
from trafilatura.settings import use_config
print('trafilatura version :', trafilatura.__version__)
html = b'''
<header>
<h1>Article Title</h1>
</header>
<article>
<h2>Related Articles</h2>
<p>Article contentArticle contentArticle contentArticle contentArticle contentArticle contentArticle content</p>
</article>
'''
cfg = use_config()
cfg.set('DEFAULT', 'EXTRACTION_STRICT', '0')
cfg.set('DEFAULT', 'MIN_OUTPUT_SIZE', '0')
txt = trafilatura.extract(html,
output_format='txt',
config=cfg,
favor_recall=True,
favor_precision=False,
include_formatting=True) # <-- 换成这个
print('---------- repr of txt ----------')
print(repr(txt))