从HTML文件中抽取正文的简单方案 试验结果 - hzxdark - ITeye技术网站

一、 简介 
本文是根据alexjc的<The Easy Way to Extract Useful Text from Arbitrary HTML>一文进行实验的结果。原文见: 
http://ai-depot.com/articles/the-easy-way-to-extract-useful-text-from-arbitrary-html/ 
——alexjc原文 

http://blog.csdn.net/lanphaday/archive/2007/08/13/1741185.aspx 
——恋花蝶翻译的中英对照版本 

该文章主要内容是讲述如何利用正文相对于其他文本,正文文本与生成该正文所需的html字节码的比值较大的规律,利用神经网络识别出正文过滤过滤广告的效果。主要设计如下: 

1. 解析HTML代码并记下处理的字节数。 
2. 以行或段的形式保存解析输出的文本。 
3. 统计每一行文本相应的HTML代码的字节数 
4. 通过计算文本相对于字节数的比率来获取文本密度 
5. 最后用神经网络来决定这一行是不是正文的一部分。 


二、 设计方案 
本实验相对原本alexjc设计方案有几点修改: 

1. 用RPROP(弹性BP网络)代替原文的感知器; 
2. 由于原文并没有把文本长度、html字节长度做归一化,所以不采用原始文本长度、html字节长度作为特征值。相对的,对归一化后的文本长度、html字节长度,以及前向后向N行等各种组合进行试验。 
3. 试验文本为任意在网上选取的10个网页,见附件。 
4. 原文并没有提及,如何定义一行文本是否正文,所以这里定义了几个正文类型: 
a) 内容型正文,特征是有长的连续文字段,定义这些文字段为正文; 
b) 论坛型,有短的不连续的文字段,定义这些文字段为正文; 
c) 论坛帖子列表型(部分试验将会对这类型进行训练查看效果,对于论坛帖子列表是否属于正文这里不做讨论……),帖子标题为正文; 
d) 首页型,定义为没有正文(厄,谁能说出,新浪首页哪些是正文?) 

实验环境: 
1. 语言:JAVA,JRE1.5 
2. 操作系统:windows xp 

三、 实验过程: 
1. 设计实现一个三层RPROP网络(令人惊讶的是,居然在这个领域没有人写一个开源的组件,apache等的开源巨头们都对neural network不感兴趣么?)。 

/* 
*初始化RPROP对象 

*本函数用于创建训练前的RPROP对象 
*参数: 
* int in_num 输入层个数; 
* int hidden_unit_num 隐含层节点个数 
* int out_num 输出层个数 

*/ 
public RPROP(int in_num, int hidden_unit_num, int out_num) 

/* 
*初始化RPROP对象 

*本函数用于创建训练后的RPROP对象 
*参数: 
* int in_num 输入层个数; 
* int hidden_unit_num 隐含层节点个数 
* int out_num 输出层个数 
* double[][] w1 隐含层权重 
* double[][] w2 输出层权重 
* double[] b1 隐含层偏离值 
* double[] b2 输出层偏离值 
*/ 
public RPROP(int in_num, int hidden_unit_num, int out_num, double[][] w1, double[][] w2, double[] b1, double[] b2) 

/* 
*计算输出结果 

*参数: 
* double[] p 输入参数 
*返回值: 
* double[] 输出结果 
*/ 
public double[] output(double[] p) 

/* 
*训练 

*参数: 
* double[][] p
* 训练样本集 
* double[][][] t
* 期望结果集, t[i][j][0] 期望结果, t[i][j][1]误差放大系数 
* double goal
* 目标误差,注意,本网络用的是“方差”作为误差判断条件 
* int epochs
* 训练最大次数 
*/ 
public void train(double[][] p, double[][][] t, double goal,int epochs) 
对于这个实现,有兴趣的朋友在本文最后下载附件。 

2. 选取特征值 
在实验中,笔者尝试了各种特征值组合: 
1) 文本密度,文本长度,html字节码长度,前后各一行的同样数值;(原文设定) 
2) 文本密度,文本长度倒数(归一化),前后各两行的同样数值; 
3) 文本所在的html的链接密度(全文文本长度/总链接数,用于加强判断文本类型),文本密度,文本长度/5000(归一化,大于1的当1处理,下文简称为文本长度2),前后两行相同的数值; 
4) 文本所在的html的链接密度,文本密度,文本长度2,前后两行相同的数值; 
5) 文本所在的html的链接密度,文本密度,文本长度2,前后一行相同的数值; 
6) 文本所在的html的链接密度,文本密度,文本长度2,前一行是否正文; 

并规定,网络输出结果0为非正文,1为正文。 

在训练过程中,发现训练过的网络命中率大部分落在0值部分,这是由于论坛这种短文段类型的网页会导致0值过多,训练时对0值过拟合。为了避免这一点,对某一篇网页的某一行的误差乘以该网页的0值与1值数量的比值。 

3. 训练集获取 
见附件。这是在笔者常浏览的网页中任意抽取的10个网页。对于期望输出的定义见上文。 

四、实验结果 
1. 1~5的实验,任意抽取部分样本集作为训练集,对于训练集拟合的很好,但对于测试集的表现却非常糟糕(请原谅笔者并没有记录实验数据); 

这部分结果表明,以文本密度作为判断是否正文的特征值是有问题的。观察样本集的数据可以发现,即使是内容型的大段文字,也有可能文本密度很低——为了让网页变得更漂亮美观,现在有很多网站都对文字内容加了大段大段修饰用html代码…… 
鉴于这一点,笔者最终放弃文本密度作为特征值。而考虑到广告都是带链接的文本,相对的正文连接数则比较少,所以笔者认为,用文本长度/链接数 作为特征值或许会是一个更好的选择。 

2. 6的实验,表现意外的非常的好(好到差点让笔者以为终于找到完美的解决方案……) 
确实,即使是在测试集部分的表现也惊人好,但实际上有一个问题:每一行的计算受上一行计算的结果影响。测试集是事先定义每一行的上一行的结果,但在实际使用时,上一行的结果是实时计算出来的,所以就会出现,在某一行出错,导致后面的结果全部出错的情况…… 

至此,假如仍然坚持神经网络的解决方案,或许,采用: 
文本长度,文本长度链接数,上一行的结果 做特征值, 采用三个弱分类器的ada-boost组合分类或许会是一个好的选择。 
除此之外,实际上对正文的定义对结果也是有很大的影响。实际上,假如能根据数据化的东西定义某一个类别,那么对于该类别的划分,或许其实已经是可预知的,不如直接设计阈值处理。 

笔者的实验则到此为止,并放弃了神经网络这个解决方案——直接采用这些特征值进行阈值判断,并对一些特殊部分设定过滤规则,这似乎比神经网络的表现来的简单、有效…… 

如果有哪位朋友感兴趣,并用ada-boost进行实验,笔者将非常期待这位朋友来交流下心得:) 

附件: 
neralNetwork.rar  源代码 
res.rar 训练集 

关于html文本抽取部分,这里用的是HtmlParser,这里修改的代码就不贴出来了,有兴趣的朋友可以去: 
http://htmlparser.sourceforge.net/ 
看看。 

 

目前互联网上公布出来的正文提取算法,大家可以综合比较下,一起来测试下哪个更好用。 词网--北京词网科技有限公司 http://demo.cikuu.com/cgi-bin/cgi-contex 猎兔网页正文提取 http://www.lietu.com/extract/ PHP版网页正文提取 http://www.woniu.us/get_content_demo/ 网页正文提取分析(DEMO) http://61.128.196.27/txt 个人认为http://61.128.196.27/txt 这个提取最牛,基本上无论什么页面都能提取出来,而且能有效的保持原文风格、图片、链接。

http://code.google.com/p/joyhtml/
看看这个效果不错
http://www.likeshow.net/article.asp?id=92  
我一年前写的玩意 虽然不完善 但尚可用之在新闻和BLOG 论坛提取上 提取的正文对于BLOG和BBS包含评论及回复 具体原理也写很清楚了
如题,想从html源码中提取正文内容,<P></P>之间的内容,但是<P>的写法不规则。除了正则表达式的方法,还有其它的提取方法吗?谢谢!
最新下载
在线演示和最新下载:
http://www.shoula.net/ParseContent 

http://www.pudn.com/downloads152/sourcecode/internet/search_engine/detail668443.html
 
 
 
 
 Google Code开源网页正文提取cx-extractor2010-05-19 12:31基于行块分布函数的通用网页正文抽取:线性时间、不建DOM树、与HTML标签无关
简述:
对于Web信息检索来说,网页正文抽取是后续处理的关键。虽然使用正则表达式可以准确的抽取某一固定格式的页面,但面对形形色色的HTML,使用规则处理难免捉襟见肘。能不能高效、准确的将一个页面的正文抽取出来,并做到在大规模网页范围内通用,这是一个直接关系上层应用的难题。
作者提出了《基于行块分布函数的通用网页正文抽取算法》,首次将网页正文抽取问题转化为求页面的行块分布函数,这种方法不用建立Dom树,不被病态HTML所累(事实上与HTML标签完全无关)。通过在线性时间内建立的行块分布函数图,直接准确定位网页正文。同时采用了统计与规则相结合的方法来处理通用性问题。作者相信简单的事情总应该用最简单的办法来解决这一亘古不变的道理。整个算法实现不足百行代码。但量不在多,在法。
项目网址:http://code.google.com/p/cx-extractor/
算法描述:基于行块分布函数的网页正文抽取算法.pdf
欢迎大家提出意见~ 
 

http://www.ngiv.cn/post/204.html
VIPS算法对搜索引擎的意义
http://blog.csdn.net/tingya/archive/2006/02/18/601954.aspx
 
基于视觉的Web页面分页算法VIPS的实现源代码下载
http://blog.csdn.net/tingya/archive/2006/04/28/694651.aspx
作者信息:飞跃,javascript教程-技术之家博客的博主 

http://www.madcn.net/?p=791

我这里有个开源的项目,还不错,你上googlecode搜索joyhtml。
http://gfnpad.blogspot.com/2009/11/blog-post.html
下面几个是一些开源的程序:
1.一个python的基于文本密度的程序:
http://ai-depot.com/articles/the-easy-way-to-extract-useful-text-from-arbitrary-html/
ps:里面有bug,要稍加改动。 另外,对于没有对html注释部分进行处理
2.Java 开源项目: Gate
http://gate.ac.uk/ 

其实可以利用Dhmtl对象进行编程分析,已获得所要的数据文件,详细请看我的程序
http://www.vbgood.com/thread-94788-1-1.html
http://download.csdn.net/source/568439
 
一.标题块
l 分块节点:td,div,h,span
l 一般位于Head/Title的位置
l 当前单元含有<h1>-<h3>,<b>,<i>,<strong>等标签
l 样式,一般class包含title,head等字符
l 文字长度,一般大于3个字符,小于35个字符
 
二.发表时间块
l 分块节点:td,div, span
l 文字长度,一般小于50个字符
l 包含日期格式(2010-08-09)的字符串
l 包含以下关键字:来源,发表
 
三.主题块
l 分块节点:td,div
l HTML网页中有一些特殊标签,通常只出现在网页主题块中,如<P><BR>等。因此,主题块中往往包含着特殊标签。
l 主题块内容含有较多的句子,因此具有较多逗号、句号等标点符号(>5)。
l 若从信息量角度考虑,主题块一般是含有较多文字信息。
l 主题块的 标签密度=1000*标签数/文字数 应在小于一个范围。
l 主题块的 文本密度=len(文本)/len(HTML代码) 较大
l 不应该包含 “上一篇”,“下一篇”
l 包含以下字符串的内容块,判定为包含版权信息,需减权:“ICP备04000001号”,“版权所有”,“Copyright”
l 主题块序号在标题块之下
l 主题块序号在发表时间块之下
l 主题块序号在相关链接块之上
 
四.相关链接块
l 分块节点:td,div
l 文字应为“相关链接”、“相关新闻”、“相关报道”等敏感词,且连接比例很高。
l 链接数小于20
 
实现:
根据以上信息块特征,采用特征提权算法,C#(3.5)编程实现,命名为QD正文提取组件。经测试,对Html格式规范的以文字为主的内容页,正确提取率在85%以上,各大门户的新闻页面在95%以上。 例子下载(需要安装Microsoft .NET Framework 3.5)
 
注:QD正文提取组件 不开源,需要源码的朋友可选择付费获取。
 
这时挑选出的正文一般也就是到位了,但是问题是很可能在头尾残留了一些块广告。我认为这些块广告与正文中广告有很大的不同。这些广告的马脚就是其父节点,它们的父节点要么也包含了正文所在区域,也就是和正文平级,要么本身就是正文所在区域的一个子节点,很难是正文节点本身的。那么对疑似正文节点进行一次扫描,剔除那些父节点文字内容过大(包含了广告以及正文,即和正文平级)的块,也剔除那些父节点文字内容过小的块。
经过这样的处理,得到的内容基本上就是我们需要的正文了。下面就是要提取标题。
在代表整个网页的document中扫描一次,寻找那些有font字体的,strong的,h1的,title的节点,提取他们的信息。然后将得到的文字内容分词,查验分出来的词有多少是被正文包含的,包含最多的一半就是标题。但是这里要注意,有时候找到的节点本身是正文节点的子节点,那么无论怎么分,分出来都是完全包含的,所以要剔除那些本身是正文一部分的疑似标题。这样做对大部分网页也是有效了,但是对仅有的标题就在正文节点里的那些页面,目前为止我还没有特别好的想法。
这些日子也研究了一些别人的论文,有很多思想都非常好,也有很多人想到用马尔科夫,人工神经来训练。也许以后我会考虑用用看吧。现在这样也还可以,呵呵。 
?
这个算法我也写了一下,不过是用C++写的。
我不太懂楼上讨论的分页是什么意思,我通过分析dom树然后用文中提到的规则进行dom结点处理以及后续的处理。
我主要是想把网页中的内容按网页框架分开,把正文部分合在一起,然后用贝叶斯决策计算正文特征支持率
提取网页内容。
现在VIPS基本写完。
但是却也发现了些问题,
比如说有些结点的坐标提取出来会有提取不出分隔条,这是因为有少数坐标有些重叠。这里涉及到一个坐标的确定问题。
然后是结点分割规则问题,现在的页面是大部分是通过DIV来组织页面。而VIPS似乎更合适TABLE组织的页面,我试过用TABLE组织的页面,分得相当不错。
另外,TINYA上面的翻译似乎改了些规则,还有部分翻译不是很准确。比如虚拟文本的定义部分与原文有些出入,不知道TINYA有没有注意到。
最后,很感谢TINYA 对这个算法的介绍。
另外,有对这个算法感兴趣的朋友希望能大家一起讨论下
我的QQ:24888086
msn:[email protected]

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tingya/archive/2006/02/18/601836.aspx
http://www.hackhome.com/InfoView/Article_119867.html

阅读全文……

你可能感兴趣的:(java,文本抽取)