原理
为所有 dom (body.childNodes)节点评分,分数最高的即为主内容节点 影响某一个节点评分的因素主要有以下几项
- 文本节点
内容不为空的数量及内容里的标点符号的数量 - 文本节点内容的长度
- 图片或 svg 的数量
- 图片或 svg 的大小
- 标签的 class 或 id 使用了内容区常用的一些字符串(如 content article 等) 这些是需要加分的
- 标签的 class 或 id 使用了非内容区常用的一些字符串 (如 head foot 等)这些是需要减分的
- 标签的位置 (比如距页面顶部都超过一屏了)这样基本就可能排除这样的节点了
实现过程
第一步:取得所有节点
取得页面的所有 dom 节点(用递归把所有的子节点 childNodes 都列出来),过滤掉不需要参与评分的节点(也就是这些节点不太可能做为主内容的容器,当然也不排除极端情况,但我们只处理绝大多数)
需要过滤掉的节点有 link img i a svg style script select input textarea
还有 nodeType = 3 的内容为空的文本节点,nodeType==8 的注释节点
循环取得节点的同时 要统计各个评分因素的数量
第二步:转化为评分
对第一步统计出来的评分因素的量转化为具体分数
第三步:排序
根据评分对节点进行一次降序排序,那么取出来的第一个就是所要找的主内容节点
注意:
如果要涵盖所有的网页,这个是不太可能的,对一些写得比较规范(页面结构清晰,class 和 id 名称运用也比较准确),内容所占的篇幅比较大的网页,那么选中主内容区的成功率是比较高的;反之,成功率就没那么高了;尤其是一些网页,可能是自动生成的,class 或 id 都是一些随机数,可能还存在大篇幅的广告区,成功率会更低。
总之,这种算法是个不断优化的过程。