深入源码,洞察迭代 14 年的高质量 html 提取方案

背景介绍

在大模型时代,开源项目的生命周期被加速了,往往迭代速度很快,但是热门项目也容易突然就无疾而终了。最近看到一款历经 14 年的开源 html 内容提取项目 python-readability,从最早建立到目前,已经迭代了 14 年。
请添加图片描述

本文是在实际项目中使用 python-readability 之后,发现一些异常 case,因此深入源码了解其中的技术细节,因此在本文中对这款跨越 14 年的开源项目的技术细节进行了解读。

项目体验与概述

在之前的 RAG 项目结构化文件解析方案比较 文章中对常见的 html 解析方案进行了比较,当时实际测试发现 html_text + python-readability 的技术方案解析效果是最好的,解析的内容组织形式是最符合人阅读形式的,并对大量无用内容进行了清理。

举例来看,使用如下所示的医学论文进行测试时,框架准确从正文部分开始内容提取,过滤了上面的作者介绍信息。
请添加图片描述

而在论文的结尾部分的解析,框架准确剔除了参考文献等低价值内容。
请添加图片描述

同时网站左侧的导航栏和与右侧的一些与内容无关的信息都被一一去除,真正所见即所得。类似的能力如果使用大模型可能相对容易理解,但是完全不借助任何人工智能的手段,如何从复杂的 html 结构中准确提取用户关注的内容,而且适配于完全不同的前端 html 结构呢。

核心的内容的提取与无关内容的清洗基本都是在 python-readability 中完成的,而 html_text 则完成了 html 元素到符合阅读形式的文本转换。本文主要就是对 python-readability 原理的详细解读,后续有空可以考虑解析下 html_text 的实现方案。

原理概述

此项目的提取核心内容的关键点在于:html 文件中主要正文内容是聚积在一起的,而那些与正文无关的内容往往散落在其他位置,比如上面例子中的作者介绍, 左侧的导航等。

因此思路就是找到一个最佳正文内容块(best_candidate),之后向四周进行扩散找到所有的正文内容块,而没有被扩散到的内容都会被丢弃。对于上面的文章,实际的结果如下所示:

请添加图片描述

作者简介就是因为无法被扩散到,从而被过滤掉。

实现细节

从上面的原理来看,主要需要关注两个核心细节:

  1. 如何找到最佳正文内容块,保证扩散的起点的准确性;
  2. 如何进行内容块的扩散,从而保证尽可能的覆盖完整的正文内容,同时尽可能避免覆盖无用内容;
最佳正文内容块的判断

最佳正文内容块的判断是基于评分机制,对所有的正文内容块进行评分,之后找到分数最高的一块作为最佳正文内容块。

选出最佳正文内容块的过程就是一个简单的排序:

sorted_candidates = sorted(
    candidates.values(), key=lambda x: x["content_score"], reverse=True
)

best_candidate = sorted_candidates[0]

因此核心就在于如何进行内容块的评分,其评分主要由两部分组成:

  1. 内容块自身获得的得分,主要基于其 html 元素中的 classtag 评分;
  2. 内容块包含的子段落得分,包含的子段落的文本段落越多,长度越长,得分就越高。

在获得得分后会根据链接密度进行评分缩放,链接过多的块得分会降低。

内容块自身得分

目前主要基于 classtag 评分,根据匹配的正则表达式确定是否应该加分还是减分:

def class_weight(self, e):
    weight = 0
    # 基于 class 进行匹配,根据匹配的积极,消极正则表达式确定分数

    for feature in [e.get("class", None), e.get(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易迟

高质量内容创作不易,支持下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值