浅谈网页阅读模式的内容提取
因为利益和技术的不同,互联网上充斥着大量的带极具不友好的网页内容,对于一个阅读内容的人来说,很多东西都是不需要的,如:页头,菜单,导航,甚至是评论,还有那万恶的广告。加上布局,字体,字体大小/颜色,背景颜色等,诸多因素都会让你的阅读体验大打折扣。所以,一个良好的阅读模式就非常的有必要了。那么,如何提取,或者说识别不同网页里的内容主体呢?这就是本文想要浅谈的内容。
1. Safari Reader
Safari很早(多早就不知道了)就有了阅读模式,为移动端提供阅读支持。Github上有它的处理JS代码(听说是从Safari里取出来的),2010年的代码。
1.1 简单原理
Safari Reader会根据页面高宽在页面上计算出9个点,如下图:
之后根据点的坐标,使用document.elementFromPoint()
来获取dom对象,然后往上遍历父节点,根据节点类型及样式值给节点打分(有一个计分方式),寻找样式相同且数量最多的节点,认为其就是内容主体。
其实这样的判断方式是没啥问题的,但仍然有相当一部分的页面内容是无法识别的,为什么无法识别这个就不太好讲。虽然代码提供有Source版本,但其实只是将压缩后的代码格式化了一下,一些核心的代码仍然很难看明白。
2. Fika
Fika是一款提供阅读模式的Chrome Extension,它开始也就是使用Safari Reader JS,但发现识别率太低后,换成了自己的实现。
2.1 简单原理
Fika认为,内容主体多数会聚焦大量的H,p,pre,code,figure等Element,所以以此为基准,获取网页dom里的所有对应Element,然后往上遍历父节点。但它只会往上找2-3层,并给这2-3层打分,离得越远,分数越低,如果属性里包含content/article等字样的额外加分。分数最高的,它认为是内容主体。这样子确实可以找到更多的内容主体,而且在目前更加规范的页面结构下,准确率相当不错。
2.2 问题
如上所说,目前Fika只会根据指定的Element去获取内容,所以,如果哪个网页的内容主体全是DIV元素,那它就失效了。而且,虽然找到了主体,但主体内部的元素仍然有不少是无用的,比如:分享,广告,表单等。虽然Fika做了一些排除,但在这一部分仍然会有很大的机率失效,虽然影响没有Safari Reader JS这样的找不到大,但总是不够完美。
2.3 改良
首先,去掉指定元素,遍历dom树时,判断标准改为元素内的#text,img,h,pre,code,figure等,如果找到就给父节点打分,那么聚焦内容越多的地方,自然就是内容主体部分。那如何去掉问题里的元素呢?
- 如果有表单元素将其父节点减分,当回到父节点时,发现分值为负或占比很低,直接将这个节点移除,再给其父节点打分。
- 如果有广告/分享,需尽量找出可能的关键字加以判断。图片在div里的分数就比在figure里低很多,层级越深,分数越低。
这样子处理后,相比之前肯定会有一个大的提升。但想要完美,并不现实。Fika想做的是,你任一打开一个网站,点开Fika,就可以得到一个相对理想的阅读体验。
结尾
在千页千面的互联网上,对于内容主体的判断还是过于理想,如果所有网站都按HTML定义的标准构建页面,那效果会很好,但标准总不会有人执行,而且还有很多网页在没有标准的时候就已经在网上了,所以,最终对内容属性的修正也是一个必要的过程,但100%估计是永远无法达到的上限。
Fika -Reader Mode