网页正文提取的思路

在不断追踪网页文本提取的技术,这篇文章中提到的做法很有实用价值!    

  网页由于格式千变万化,要找到一种能提取任意网页正文的算法,并能达到应用需要的准确度,具有一定难度。因此,总避免不了在提取程序中添加一些规则,对不同的网页类型作不同处理。另外,有人利用开源的Tidy,把不规范的网页规范化,然后利用DOM Tree,把包含正文的<talbe>...</table>提取出来,然后去除其中的链接信息。 还有一种简单的方法:对网页中的所有<table> ...</table>,计算其中所含内容中的中文标点符号,并结合内容中所包含的链接数,综合判断,以确定到底哪个<table>...</table>最有可能为正文。具体的判断方法,可以通过实验观察来确定。

规则解决不了一切,但是可以解决一大部分问题。如果弄一个马上可以用的,规则是最好的方法。如果是做研究,自动抽取规则,或者识别网页中的block信息应该是不错方法,目前已经有相关文章了。

基于视觉的是比较新的,不过,基于分块识别的也还可以。广告部分有比较多的链接。

         正文一般应该是网页中最长的部分,我这次要介绍的是如何抽取正文,这部分是最为核心的.因为如果不能很好的提取原有文章的内容和样式,那么搜索出来的东西就会惨不忍睹.根本就没有使用价值。在做正文抽取模块之前我曾经参考过很多抽取模式,有配置模版的,有搞视觉匹配的.有搞关键字识别的.我挨个做了分析首先配置摸版是不太现实的,因为我在搜索技术资讯的时候,根本不知道会搜索到哪个网站,也根本没精力去配置摸版.所以这个行不通。基于视觉效果的分析,这个难度比较大,而且只适合于规范的网站,而现在很多网站根本不规范,广告链接漫天飞.人家都把最好的位置留给广告了.而且我一直怀疑这个模式的可行性,它只是一个善意的推测.所以这方面没做过多尝试。我在想,是否有种简单的方法呢?难道就没有什么共性吗?

  我想所有的正文应该有个共同的特点,那就是正文的长度应该超过其他文字组合的长度.很少会有一句话的正文,很少会有长度短于标题的正文.所以这个应该成为一个突破口.

  接下来,有一个很重要的问题,那段最长的正文在哪里呢?肯定是在一个TABLE,或者DIV,或者ParagraphTag里.那好,那就找到那个包含文字最多的DIV或者TABLE.不过问题又来了,HTML页面,经常是HTML元素的长度超过了正文的长度,有时候混入了不少的JAVASCRIPT.这些元素HTMLPARSER经常会误认为是正文加以识别,导致很多正文竟然是一段JAVASCRIPT.
  祛除杂质是一个关键,这里面要把那些HTML中常用的标签,以及连接中正文去除掉,否则,你搜索出来的很可能是别的什么,尤其当正文文字相对较少的时候.我在搜索SOHU页面的时候就经常遇到这个问题,原因是SOHU的页面不是严格按照DIV布局,里面有很多广告的JAVASCRIPT。新浪的有些页面也有这个现象,反到是一些中小网站的布局很规范,呵呵,真奇怪了。

  做完这些工作后,我发现仍然有些网页不能正常抓取,原因是HTMLPARSER对TEXT的认识有问题.例如一段文字在ParagraphTag中或者span中包含的,就不能很好的识别.所以要单独做个抽取ParagraphTag内容的函数.

  做完这些步骤后,有一个问题出来了就是正文中包含的图片,连接,粗体,正常的表格.这些问题一个个的冒出来.既然问题出来了那就要一个个的解决.解决了这些难题.我的网站抓取文章的质量就大大的提高了85%的准确率,基本达到实用阶段.我网站上的正文快照基本和原文保持一致.

-----------------------------------------------------------------------------------------------------------------------------------

蛙蛙推荐:基于标记窗的网页正文提取算法的一些细节问题

   网页的正文提取有好多种算法,有基于视觉的,基于标记窗的,基于双层决策等算法,这里讨论一些基于标记窗的算法(相对简单且效果还好)的相关细节问题,如下

    问题:如何提取一个网页的标题
    思路:提取网页的title,提取网页的meta里的keyword,提取网页里的所有h标签,先用title和keyword比,把title里的 keyword去掉,因为某些网站做SEO,在keyword和title里都有关键词堆叠,所以去掉重复的项,一般就是网页内容的标题了。一般一个网站的所有网页的keyword都相同,但碰上每个网页的meta keyword和本页内容相关这个算法就不灵了。然后再计算裁剪后的title和h标签(有限h1,h2次之)里提取的文本的文本相似度或者编辑距离,如果少于某个阈值,这个h标签的文本就是网页的标题。另外还要考虑title和正文标题一点关系都没有的情况。提取标题的算法有好多不可靠性,实在不行就直接去title了。

    问题:如下文字,两个横杠之间的文字,

==================================================
<div>没有花香,
没有树高</div><td>((:&nbsp;那就等 着沦陷吧,如果爱情真伟大</td>
<div>我早已为你种下<b>九百九十九</b>多 玫瑰</div>
<div>妹妹你坐船头,<td>哥哥我岸上走sdf</td></div>
==================================================

    用正则分成以下几组字符串,引号引住的部分

    1、"没有花香,\r\n没有树高"
    2、" 那就等着沦陷吧,如果爱情真伟大"
    3、"我早已为你种下九百九十九多玫瑰"
    4、"妹妹你坐船头,哥哥我岸上走sdf"
    5、"哥哥我岸上走sdf"

     思路:其实就是取出html容器标签(td,div,span,p等)里的汉字部分,并且如果是嵌套容器的话,最里层的匹配一个分组,一直向外,每层算一个分组,最后把每个分组弄成一个字符串的列表

    问题:如何用正则把一段html文本块取出其带格式的文本
    思路:首先要去掉修饰性标签,<b>,<font>还有<img>等,其次要把<br>替换成\r\ n,&nbsp;替换成空格,再把<srcipt><style>等标签及其中间的字符都去了,想<a title="嘿嘿">这个标签里的"嘿嘿"不能算是正文,正文中的链接不能去掉,要改成“百度(http://www.baidu.com/)”这样的格式,否则提取文本后链接信息就没了。

    问题:一个标题和多个正文,如何用程序来判断这个标题属于这个正文的
    思路:把标题用中科院分词系统分词,然后去除停止词,然后根据词性标注把实词取出来,记为S,然后看每个正文里S里的每个词出现的次数,无论哪个词,取出现次数最多的那个正文就是这个标题的正文,我觉得这个思路比把标题和正文都切词后用编辑距离比较的算法更准一些,而且正文和标题切词后是两个字符串数组,两个字符串数组貌似没有现成的算法算他们之间的距离的。

    问题:有若干段儿html文本块,去掉大多数为超链接的文本块
    思路:先算出每个文本块中所有汉字的数量,再算出每个文本块中被<a>标签包围的汉字数量,如果这两个值的比例大于某个阈值,就删除这个文本块

    以上几个文本解决后,网页的正文提取就能做的差不多了,最起码有百分之七八十的正确率吧。大家有兴趣和我一起解决哦,呵呵呵。

----------------------------------------------------------------------------------------------------------------------------------

一般是用DOM的方法
不过抽取的时候 要分authority和hub网页分开处理
还有bbs网页
bbs网页最好采用xpath的方法
每个名次都是一系列的技术
一般的authority网页可以用DOM的比较方法
需要注意div和table 一般网页的内容都放在里面

posted on 2012-04-14 09:59  fancing  阅读(2241)  评论(0编辑  收藏  举报