摘要
Boilerpipe是一个非常优秀的网页正文抽取库,作者是Christian Kohlschütter
,在抽取新闻和博客正文时,准确率非常高,基本开箱即用,著名的信息抽取工具Tika
也使用了Boilerpipe
作为网页内容自动提取的第三方库,还有很多python用户对其进行了封装。
1. 算法效果展示
(注:这里使用的是改进后的算法,具体改进请参考后文。)
使用Boilerpipe
自带的测试的测试模块对效果进行测试,测试数据选择了人民网的一篇财经类新闻。
public class Oneliner {
public static void main(final String[] args) throws Exception {
final URL url =
new URL("http://finance.people.com.cn/n1/2021/0303/c1004-32041507.html");
System.out.println(ArticleExtractor.INSTANCE.getText(url));
}
}
提取正文如下:
可见提取准确率非常高,基本开箱即用。
2. 核心代码解读
论文地址:
http://www.l3s.de/~kohlschuetter/publications/wsdm187-kohlschuetter.pdf
代码地址:
http://code.google.com/p/boilerpipe/
算法的核心是决策树,论文中提到作者选择了很多特征完成决策树的训练,但是最终在剪枝阶段,把大部分的特征都去掉了,保留了很少的特征。
public boolean process(TextDocument doc) throws BoilerpipeProcessingException {
return TerminatingBlocksFinder.INSTANCE.process(doc) |
(new DocumentTitleMatchClassifier(doc.getTitle())).process(doc) |
DensityRulesClassifier.INSTANCE.process(doc) |
ChineseTerminatingBlocksFinder.INSTANCE.process(doc) |
//略
LargeBlockSameTagLevelToContentFilter.INSTANCE.process(doc) |
ListAtEndFilter.INSTANCE.process(doc);
}
DensityRulesClassifier就是决策树的实现类。
可以看到决策树使用的特征分别是链接密度
和文本密度
。这两个密度在网页正文抽取领域非常常用,但是作者通过决策树算法,把最佳的密度给跑出来了,所以效果很好。
protected boolean classify(TextBlock prev, TextBlock curr, TextBlock next) {
boolean isContent;
if ((double)curr.getLinkDensity() <= 0.333333D) {
if ((double)prev.getLinkDensity() <= 0.555556D) {
if (curr.getTextDensity() <= 9.0F) {
if (next.getTextDensity() <= 10.0F) {
if (prev.getTextDensity() <= 4.0F) {
isContent = false;
} else {
isContent = true;
}
} else {
isContent = true;
}
} else if (next.getTextDensity() == 0.0F) {
isContent = false;
} else {
isContent = true;
}
} else if (next.getTextDensity() <= 11.0F) {
isContent = false;
} else {
isContent = true;
}
} else {
isContent = false;
}
return curr.setIsContent(isContent);
}
链接密度和文本密度的计算方式如下。
# 文本密度:行的总词语数量/行数量
textDensity = numWordsInWrappedLines / (float) numWrappedLines;
# 链接密度:链接文本的词语数量/总词语数量
linkDensity = numWords == 0 ? 0 : numWordsInAnchorText / (float) numWords;
3. 算法问题和改进
原算法是依赖词语数量的,对于英文的分词,只要依赖空格就可以了,但是对于中文,就要单独做分词。如果要让算法处理中文网页,需要改进原算法的分词方式。
有两种方案,一种是按字分词,另一种是按词语分词。可以选用一个开源的分词软件(比如Jieba、HanLP等)对文本进行分词,然后再计算词语数量。
4. 小结
本文介绍了网页正文抽取boilerpipe算法,这个算法的核心是决策树学习,通过大量数据学习模型参数,并利用剪枝大大简化了特征数量,通过改进词语数量计算的方法,可以直接移植到中文网页的正文提取项目中。