newspaper4k 在 22/22 个受控文章样本中的输出表现

最后更新于 August 17, 2026
newspaper4k 在 22/22 个受控文章样本中的输出表现
AI 摘要
Across one annotated, article-oriented fixture set, newspaper4k produced output on all 22 fixtures, recovered 98.65% of scored article units, and included none of the labeled boilerplate tokens. Those three dimensions make it a strong candidate under this test's priorities; they do not define a universal winner. Nothing else in this set combined those three observed results. Mozilla Readability recovered every scored content unit but included more labeled boilerplate; goose3 included no labeled boilerplate but returned empty strings twice. Other decision rules can prefer another library.

在这一组带标注、以文章为中心的样本中,newspaper4k 在 全部 22 个样本 上都成功输出结果,找回了 98.65% 的评分文章单元,并且没有包含任何标注为 boilerplate 的标记。就这三个维度来看,它非常贴合这次测试的优先目标;但这并不意味着它就是放之四海而皆准的最佳选择。

在这组样本里,没有任何其他工具能同时达到这三个观察结果。Mozilla Readability 找回了所有评分内容单元,但混入了更多标注 boilerplate;goose3 没有引入任何标注 boilerplate,但有两次返回空字符串。不同的判断标准下,其他库也可能更合适。

在正式部署前,有一个默认抓取行为尤其值得单独留意。

newspaper4k 是什么

newspaper4k 是 newspaper3k 的一个维护分支,而 newspaper3k 本身又是原始 newspaper 的 Python 3 延续。这个传承很重要,因为当你在网上找帮助时,大多数资料讲的都是它的前身,而部分 API 也已经发生了变化。

官方参考:newspaper4k 官方仓库

System diagram: Article Extraction Pipeline

这类库最容易用错的地方之一,就是去调用 set_html()。这个方法并不存在。HTML 应该通过 download() 传入:

from newspaper import Article
a = Article(url="https://example.com/story")
a.download(input_html=html)     # 不是 set_html()
a.parse()
text = a.text

我第一次运行时就把这一点搞错了,在确认问题是不是出在我自己之前,一度把这个库在 22 个样本上记成了 0 分。事实证明是我搞错了。

它返回的不只是文本。Article 对象还会暴露 texttitleauthorspublish_datetop_imageimagesmoviesmeta_descriptionmeta_langtagsarticle_html 等字段。keywordssummary 则需要额外安装 NLP 相关组件,并完成下文提到的语料配置。这里虽然盘点了字段覆盖面,但没有对元数据准确性做评分。

测试版本:0.9.6,MIT 许可证,1,135 个 GitHub stars,仓库最近一次推送日期为 2026-07-31。这个时间点只代表一个快照,不能直接等同于维护健康状况。Python 3.14.2。

测试结果

文章召回率(共 22 个)boilerplate 泄漏内容 token 精度污染 token 数输出样本数
Readability1.00000.23530.91093522/22
trafilatura0.98650.05880.9411422/22
newspaper4k0.98650.00000.9452022/22
resiliparse0.90540.05880.9381722/22
jusText0.83780.47060.87607419/22
goose30.82430.00001.0000020/22

sixway-scores.json。每个样本中的每个单元都带有唯一的哨兵 token,因此“找回”和“泄漏”都不是相似度分数,而是精确的子串包含判断。召回率统计覆盖全部 22 个样本;泄漏率和精度则统计同时包含文章内容和 boilerplate 的 11 个样本。

有三列需要分开看。

它回答了每一页。 goose3 和 jusText 没做到这一点——分别只覆盖了 22 个中的 20 个和 19 个。这个差异比表面看起来更重要,因为像这里这样的 precision 和 F1,都建立在“已经输出结果”这个前提上:如果某个库返回空字符串,它既不会拉高也不会拉低比例,因此“拒答”反而是免费的。goose3 的 1.0000 precision 只是在 11 个样本中的 10 个上计算出来的;newspaper4k 的 0.9452 则覆盖了 11 个中的 11 个。这两者并不是完全同一种测量口径。

它没有泄漏任何内容。 这些样本里故意加入了带对抗性的 boilerplate——例如与文章并列出现的中性类促销块、使用看似无害类名的评论线程、以及不会直接写“ad”的广告块。Readability 的 sibling-append 规则吞进去了好几个,而 newspaper4k 一个都没漏。

它在 74 个单元里只漏了 1 个,而且漏掉的还是共享项。

漏掉的是非纯文本样本——这是一页由表格、代码块、短条目和图片说明组成,而不是普通段落;它丢失的单元是 caption。不过它并不是唯一一个在这里出问题的库:

非纯文本页面召回率丢失的单元
Readability1.000
jusText1.000
trafilatura0.875caption
resiliparse0.875caption
newspaper4k0.875caption
goose30.250两个表格、代码块、两个短条目、caption

有三个库都丢掉了同一个 caption,没有其他单元,这更像是它们共享了某种“caption 应该有多重要”的继承性假设,而不是三个独立 bug。如果你的内容是文档、食谱,或者任何 caption 里包含段落外关键信息的页面,那么在正式采用前最好先做验证——Readability 和 jusText 在这点上都保住了它。

同一个样本也是 goose3 完全失手的地方,它丢掉了整页四分之三的内容,因此“非纯文本内容”是一个维度,而这六个库之间在这个维度上的差异,比总览表格看起来要大得多。

在速度方面,newspaper4k 在这 22 个样本上的中位抽取时间是 2.69 ms,是六个库里最慢的,最差一次达到 199.81 ms。对比 resiliparse 的 0.06 ms 中位数,在这次受控测试中差了 45 倍。单页流程里这个中位数也许不算什么,但高负载下的吞吐量和尾延迟并没有测试。冷启动导入时间会在下文单独说明。

第一行我会改掉的默认值

System diagram: The default I would change on line one

官方参考:newspaper4k 文档

查看随包提供的 Configuration 对象会发现有 22 个设置。其中一个是:

System diagram: Separate Fetching From Extraction

_honor_robotstxt = False

如果你不特别说明,newspaper4k 默认并不遵守 robots.txt。如果你让它自己去抓取——也就是直接调用 Article(url).download(),而不传 input_html——它会抓取你指定的任何地址,不管站点的 robots 文件怎么写。

对于主要用途是解析你手上已有 HTML 的库来说,这个默认行为在工程上说得通;但如果你在生产环境里把它指向了一千个 URL,之后才发现这一点,那就完全站不住脚了。要么在 Configuration 里把 honor_robotstxt=True 打开,要么像我在这次测试里一样,直接传入 input_html,让自己负责抓取。

还有两个默认值也值得知道:

number_threads = 10 它的多文章辅助方法默认并发数是 10。并发不等于每秒请求数,但如果你没有为单个主机设置明确限速和调度,它仍然可能制造一波并发请求。

fetch_images = True 图片抓取默认开启,这会带来离线使用方面的问题。在阻断 socket.connect 的情况下,本次测试的 newspaper4k 0.9.6 路径——对单个已持有 HTML 的输入执行 download(input_html=…) 然后 parse()——成功完成,返回了 1,292 个字符,并尝试了 0 次网络连接。这只能说明这一条明确路径可行,并不能代表所有配置、插件、内容类型或未来版本都同样如此。

其余默认值都比较合理:min_word_count 300,min_sent_count 7,max_text 100,000,http_success_only 为 True,memorize_articles 为 True,follow_meta_refresh 为 False,allow_binary_content 为 False。

安装现实情况

执行 pip install newspaper4k 会拉取 22 个包47.5 MiB 内容,大约耗时六秒。在全新的子进程里进行冷导入:2.812 秒——这是对比中最慢的。

包数量site-packages 大小冷导入时间抽取 p50
resiliparse521.0 MiB0.015 s0.06 ms
jusText322.4 MiB0.777 s0.56 ms
goose31644.3 MiB2.181 s1.85 ms
newspaper4k2247.5 MiB2.812 s2.69 ms
trafilatura1769.9 MiB1.584 s0.51 ms

install-and-import.json。每个库都在独立的空虚拟环境中测试,因此不会继承其他库的依赖。

2.812 秒的导入时间是 resiliparse 15 毫秒的 187 倍。如果你运行的是长生命周期 worker,这个成本只付一次,问题不大;但如果你在 serverless 函数里跑,每次冷启动都要付这笔账,那 newspaper4k 就不是合适的选择,不管它的抽取质量有多好。

安装方面还有一个小瑕疵。导入时会打印警告:

UserWarning: nltk is not installed. Some NLP features will be unavailable. Install it with: pip install 'newspaper4k[nlp]'

本次测试并没有用到这些功能,而且即使没有它们,抽取也完全正常;但基础安装并不等于完整安装,而 newspaper4k[nlp] 会额外引入更重的依赖树以及语料下载。只有在你确实需要关键词和摘要时,才值得为它预留这部分成本。

内存,以及坏 HTML 会把它变成什么样

这批评测里,另有两项在各篇评测中都标为“未测试”的内容,现在也补上了测量结果。

更完整的压力测试背景见:十个库的内存与畸形 HTML 对比

峰值常驻内存,通过 /usr/bin/time -l 获取,每个单元都在一个全新进程中运行——导入底线代表库在“加载并空闲”时的成本,峰值则包含了文档处理开销。

运行环境导入底线(MiB)226 KB HTML 峰值(MiB)10 MB HTML 峰值(MiB)
html2textpython3.1418.719.971.2
pyquerypython3.1430.333.9172.5
resiliparsepython3.1420.525.1225.1
markdownifypython3.1423.928.9278.5
goose3python3.1444.152.4398.5
cheerionode2266.876.5398.5
justextpython3.1430.336.6431.2
newspaper4kpython3.1452.661.8668.5
trafilaturapython3.1452.564.8927.1
turndownnode2247.868.42947.1

memory-results.json。Python 和 Node 的基线不适合直接横向比较;解释器本身就包含在两者之内。

newspaper4k 的导入底线是 52.6 MiB,10 MB HTML 的峰值达到 668.5 MiB——在 Python 库里是第二重的。对于普通网页来说,这两个数字都不算问题;但如果你在内存受限的 worker 里批量处理大文档,它们就很关键了。

畸形 HTML。 这里有 12 个文档,每个都只破坏一件事——例如未闭合标签、嵌套错误的行内元素、带空格却未加引号的属性、多余的闭合标签、完全没有 <html>、重复属性、文档在标签中间被截断、错误实体、未闭合的 <script>、错误的 charset 声明、包含 markup 的注释,以及 600 层嵌套——另外再加上 2 个格式正确但尺寸匹配的对照样本,因为“它什么都没返回”只有在库面对同样大小的正常文档也一样沉默时,才说明它真的受到了 malformed 的影响。

原始结果里,正常对照和畸形样本分得很清楚:

分组文档数报错空输出找回的评分哨兵 token
正常且尺寸匹配的对照样本200不计入畸形评分
畸形样本120105/33,不含未闭合的<script> 情况

那两个对照样本分别输出了 70 和 1,351 个字符,而 12 个畸形输入中有 10 个返回了空字符串。这样就能把“沉默”明确归因于样本的畸形性,而不是单纯输入太短。评分器会在 11 个可计分的畸形文档中检查标题、段落和链接哨兵 token。未闭合的 <script> 样本被排除在外,因为按照 HTML5 解析规则,后续标记会继续被视为 script 内容。见 malformed-results.json。这是一项重要的恢复能力限制,在选型时必须带上,而不只是“没有报错”这么简单。

优缺点

优点。 在这次对比中没有引入任何标注 boilerplate token,22 个受控文章样本全部有输出,文章召回率达到 0.9865。它会暴露文章文本以及元数据字段,不过元数据准确性并未测试。在 socket.connect 被阻断时,测试用的已持有 HTML 路径没有尝试网络连接。检查时仓库最近有过时间明确的推送;但更广义的维护健康度没有评估。

缺点。 这组测试里冷启动导入最慢,达到 2.812 秒,而且 measured 的 site-packages 体积为 22 个包 / 47.5 MiB。honor_robotstxt 默认是 False,多文章辅助方法默认开启 10 线程。基础安装还会提示缺少 NLTK,因此关键词和摘要功能需要更重的可选安装。最关键的是,12 个畸形样本里有 10 个返回空输出,尽管两个格式正确的对照样本都能正常产出文本。

谁适合用,谁不适合用

适合考虑 newspaper4k 的场景:你的优先级是——在受控的文章类语料上产出非空文本、尽量减少该语料中的标注 boilerplate、并且可以接受较慢的冷启动导入。如果按这个明确规则,它在本次样本对比里是领先的。若标准不同,Readability 可能更适合追求最高内容保留率,而 resiliparse 更适合追求启动和中位抽取速度。

建议跳过或先认真做 bake test 的场景:冷启动非常关键、47.5 MiB 的 measured site-packages 体积已经成为问题、或者你很在意畸形 HTML 的恢复能力。这里 resiliparse 的导入速度快了 187 倍,但它在整体质量列上并没有和 trafilatura 完全打平:trafilatura 的文章召回率更高,而它们在泄漏和精度上的表现也不同。newspaper4k 是面向文章的;商品列表和仪表盘并没有测试,所以这里不能对它们做任何结论。

无论如何,只要你让它抓取,就把 honor_robotstxt 打开。 这不是一条性能建议。

托管 API 适合放在哪里

newspaper4k 既可以解析调用方提供的 HTML,也有自己的抓取路径。托管式抽取服务则把获取、渲染和 schema 处理放到供应商边界之后。我们自己在做 Thunderbit,但这次并没有把它放进这组样本里跑,所以这里不能拿它做质量、渲染、反爬、延迟或成本对比。对于已经拿到手的文章 HTML,这里的证据只说明 newspaper4k 本身;非文章目标需要单独评估。

想看这六个抽取器在同一批样本上的表现,可以参考 六库抽取对比

如果你关注的是托管方案,我们的 网页抓取 API 盘点 提供更大的视角;如果你想看自托管替代方案,可以读 开源爬虫总览。如果最终文本要送进模型,Python 中把 HTML 转成 Markdown 这篇会说明信息在什么环节开始流失。

试试 Thunderbit 进行网页数据提取

该不该用 newspaper4k?

如果你已经有 HTML,newspaper4k 是文章文本抽取的强力候选;但在正式采用前,最好先用自己的真实站点语料做一次对比测试。受控样本显示,它的文章召回率很高、没有标注 boilerplate,而且在全部 22 个文章类样本上都能输出非空结果。与此同时,它并不覆盖真实网页或元数据准确性,而且 12 个畸形样本里有 10 个返回了空输出。

如果你会用它的抓取路径,请明确检查 honor_robotstxt=False、10 线程并发,以及按主机设置限速控制。如果冷启动或依赖体积很重要,请把本地 2.812 秒导入时间和 47.5 MiB site-packages 的观察结果放到你的实际部署环境里测,而不要把它们想当然地当成通用容器成本。

试试 Thunderbit 进行网页数据提取 Get Started Free

常见问题

为什么 set_html() 不能用? 因为 newspaper4k 里根本没有这个方法。HTML 应该通过 download(input_html=html) 传入,然后再调用 parse()。搜索结果里可能会出现 newspaper3k 的示例,所以这个错误很容易犯;我第一次跑的时候就犯了,后来在打分前把测试框架修正了。

newspaper4k 会遵守 robots.txt 吗? 默认不会。honor_robotstxt 的出厂值是 False。如果你让库自己抓取,请在 Configuration 里设成 True;或者直接传入 input_html,由你自己负责抓取。多文章任务默认还会使用 10 线程并发。这只是未经你选择的并发度,不是固定请求速率;抓取时请自行设置明确的主机级限速。

parse() 会发起网络请求吗? 在 newspaper4k 0.9.6 上,本次测试的 download(input_html=…)parse() 路径,在 socket.connect 被阻断时,对一个已持有 HTML 的输入没有发起任何连接尝试。这并不能证明所有解析配置、插件、内容类型或未来版本都不会联网。

导入时的 NLTK 警告是什么意思? 基础安装不包含 NLTK,所以关键词提取和摘要功能不可用,库会在导入时明确提示。抽取本身不受影响——这里测到的所有结果都来自基础安装。pip install 'newspaper4k[nlp]' 会把这些功能装上,但也会带来更重的依赖树和语料下载。

这次评测没有测试什么? 没有测试真实世界网页——这里全都是带标注的受控样本。元数据字段虽然有盘点,但没有对标题、作者、日期或图片准确性打分。也没有测试多语言抽取、NLP 扩展、多线程源站抓取,以及高负载下的吞吐量。进程峰值内存只在一个 226 KB 和一个 10 MB 的 HTML 输入上测过,没有并发和持续负载场景。

Ke
Ke
Thunderbit 首席技术官 | 高级数据科学家与机器学习专家 Ke Shen 拥有近十年的机器学习和数据科学经验,毕业于哥伦比亚大学,曾任 Walmart Labs 高级数据科学家。他在 Python、R、Java 和统计学方面拥有深厚且备受同行认可的专业能力,并分享如何将复杂的 AI 算法从理论落地到生产级架构的实战经验。
目录
Thunderbit · AI 网页数据代理

一键 内提取任意页面数据

深受 250,000+ 用户信赖
提供免费方案
从网页到表格
描述你的需求——Thunderbit 的 AI 代理会帮你抓取并导出到 Excel、Google Sheets、Airtable 或 Notion。可免费开始。
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week