开发这个项目,源自于我在知网发现了一篇关于自动化抽取新闻类网站正文的算法论文——《基于文本及符号密度的网页正文提取方法》
这篇论文中描述的算法看起来简洁清晰,并且符合逻辑。但由于论文中只讲了算法原理,并没有具体的语言实现,所以我使用 Python 根据论文实现了这个抽取器。并分别使用今日头条、网易新闻、游民星空、观察者网、凤凰网、腾讯新闻、ReadHub、新浪新闻做了测试,发现提取效果非常出色,几乎能够达到100%的准确率。
在论文中描述的正文提取基础上,我增加了标题、发布时间和文章作者的自动化探测与提取功能。
最后的输出效果如下图所示:
目前这个项目是一个非常非常早期的 Demo,发布出来是希望能够尽快得到大家的使用反馈,从而能够更好地有针对性地进行开发。
本项目取名为抽取器
,而不是爬虫
,是为了规避不必要的风险,因此,本项目的输入是 HTML,输出是一个字典。请自行使用恰当的方法获取目标网站的 HTML。
本项目现在不会,将来也不会提供主动请求网站 HTML 的功能。
项目代码中的GeneralNewsCrawler.py
提供了本项目的基本使用示例。
test
文件夹中开发者工具
,如下图所示:
Elements
标签页定位到<html>
标签,并右键,选择Copy
-Copy OuterHTML
,如下图所示JavaScript渲染后的
源代码。from GeneralNewsCrawler import GeneralNewsExtractor
extractor = GeneralNewsExtractor()
html = '你的目标网页正文'
result = extractor.extract(html)
print(result)
对大多数新闻页面而言,以上的写法就能够解决问题了。
但某些新闻网页下面会有评论,评论里面可能存在长篇大论,它们会看起来比真正的新闻正文更像是正文,因此extractor.extract()
方法还有一个默认参数noise_mode_list
,用于在网页预处理时提前把评论区域整个移除。
noise_mode_list
的值是一个列表,列表里面的每一个元素都是 XPath,对应了你需要提前移除的,可能会导致干扰的目标标签。
例如,观察者网
下面的评论区域对应的Xpath 为//div[@class="comment-list"]
。所以在提取观察者网时,为了防止评论干扰,就可以加上这个参数:
result = extractor.extract(html, noise_node_list=['//div[@class="comment-list"]'])
test
文件夹中的网页的提取结果,请查看result.txt
。
在使用 Python 实现这个抽取器的过程中,我发现论文里面的公式和方法存在一些纰漏,会导致部分节点报错。我将会单独写几篇文章来介绍这里的修改。
项目地址:https://github.com/kingname/GeneralNewsExtractor
也可以点击阅读原文跳转到项目源代码。