3信息提取原理与算法
对Web页面的信息提取主要表现在对其标记节点和文本内容的分析,构造出健壮的包装器。信息抽取的规则在包装器中占有很重要的地位。文献[4]提出利用隐马尔可夫模型提取文档的元数据信息的方法, 但其只关注于提取文档头部的元数据信息。Kushmerick等人对具有HLRT(head-left-right-tail)结构的Web页面使用LR分隔符集表达包装器[5]。但是该方法只针对格式特别规整的表结构,有其局限性。抽取工具TSIMMIS、W4F等,采用了一些基于Web文档结构的抽取规则,可以根据结构树中的节点准确定位HTML页面中的TAG标记,能够准确定位到所要抽取信息的位置,不会与其他具有类似结构的数据相混淆。但是当页面结构发生了变化,结构中的任一个层次发生微小的改变就会最终影响到抽取规则的失效性。NoDoSE、WHISK、STALKER等抽取工具,采用基于特征模式匹配的抽取规则,能够在Web文档的全文中识别具有特征模式的子串,不需要结构层次的信息,对于网页结构变化多的一类的网页能够很好地处理。但是,没有结构层次信息的支持,缺少对文本的定位信息,抽取过程易被具有类似结构的其他数据所干扰。针对这些问题,本文结合文档结构定位的准确性与特征模式匹配的自由性两种优势进行Web页面的信息抽取,可以对电子期刊资源信息进行精确抽取。
基于结构的信息抽取技术主要采用HTML中所包含的结构特征、位置特征、显示特征、语义特征和引用特征形成抽取规则。抽取规则主要包括抽取路径、左右邻标志及节点特征等。
本文原文 由于所需抽取信息的左右邻标志可能与页面中的其他信息的左右邻标志产生冲突,将并不需要的信息抽取出来。在抽取信息时需要限定抽取的整体范围,确定从HTML文档中什么地方开始抽取,直到什么地方结束。这样可减少产生冲突的范围。
HtmlParser是一个对现有的HTML进行分析的快速实时的解析器,主要依靠HtmlParser中的Node来表达HTML。Node是形成树结构表示HTML的基础,所有的数据表示均是接口Node的实现。Node定义了与页面树结构所表达的页面Page对象,获取父、子、兄弟节点的方法,节点到对应HTML文本的方法,该节点对应的起止位置,过滤方法及Visitor访问机制。Node分成三类:RemarkNode代表HTML中的注释;TagNode代表标签节点,是种类最多的节点类型;TextNode表示文本节点。需要提取的信息主要就是TextNode表示的文本节点所对应的文本信息。
通过分析待抽取信息标签节点的特征,过滤掉与其特征不相关的标签节点,然后根据其所在路径,可以精确定位信息所在的位置。以抽取维普中的信息为例,代码如下:
Parser parser=new Parser();
//括号中应填上带抽取页面存放本地硬盘位置或其URL地址
parser.setEncoding("UTF-8");//设定解析编码格式
NodeFilter filter=null;//初始化节点过滤器
filter=new TagNameFilter("div");//过滤掉不是div的节点
NodeList list=parser.parse(filter); //将过滤后的节点存入数组中
Node node=list.elementAt(1);
//确定待抽取信息的节点,即确定抽取范围
利用递归方法在带抽取信息的节点中将文本节点信息存入数组,然后根据带抽取的每条信息的结构特征,可以通过正则表达式构造匹配模式,以供抽取时的模式匹配。
正则表达式(regular expression)就是一个字符构成的串,由一些普通的字符和一些元字符组成。它定义了一个用来搜索匹配字符串的模式,能够明确地描述文本字符串的匹配模式。如“〈title〉(.*)〈/title〉”可以抽取出网页中的标题。其中:“.”可以表示任何字符;“*”表示前面类型的字符可以出现零次或者多次。
信息抽取算法具体如下:
设Web页面标记节点集合N={node1,node2,…,nodem},T={t1,t2,…,tn}为所定义的特征模式集合。
输入:待抽取信息的网页;
输出:本网页上的标题、作者、地址、关键词、摘要、分类号和期刊号等各种元数据信息。
算法:
建立需要输出的元数据信息列表List,初始化i=1,j=1,信息块集合IB为空;
通过文档定位方式从集合N中找出所有信息项最近的父标签节点nodek(1≤k≤m);
深度遍历nodek中的节点,通过递归调用将找到的文本信息节点nodeIj(j≥1,且按自然数递增)放入集合IB中,最后得到集合IB={nodeI1,nodeI2,…,nodeIl}。
while(i<=l)
{
读取文本信息节点nodeIi;
信息节点nodeIi与T中的每个特征模式进行匹配;
if(匹配成功)
{
产生抽取结果R;
if(List为空)
将R加入列表List;
if(List非空)
{
将R和List中的每项抽取结果进行比较,如果没有相同,则将其加入列表List中;
}
}
i=i+1;
}
|