一种基于期望列表的网页内容抽取方法
【专利摘要】本发明公开了一种基于期望列表的网页内容抽取方法,使用bison和flex库将XPath表达式解析为链表结构;读取XML文件文本;将XPath链表的头节点加入到期望列表中;对于XML文本和XPath链表,根据状态机的状态,重复执行匹配行为。如果在期望列表中查询到有名称相同的项,则检查该项对应的链表节点是否有下一个元素。如果有,将下一个元素加入期望列表中。如果没有,表示XPath的匹配工作完成,将该节点作为结果返回。如果指针指向了标签的末尾,则期望列表入栈,清理上下文。如果指针指向了闭合标签的末尾,则期望列表出栈,还原上下文;当读取指针指向XML文件的末尾时,则结束。本发明跳过不必要的分析。
【专利说明】一种基于期望列表的网页内容抽取方法
【技术领域】
[0001]本发明属于计算机【技术领域】,涉及一种基于期望列表的网页内容抽取方法。
【背景技术】
[0002]Xpath是一种表达XML节点路径的表达式,可以方便的定位到XML的一个节点。XPath的处理是网页分析的一项常规工作,需要把一个网页作为XML文件作为输入流,给XPath引擎处理,最后输出定位的文本。XPath的分析速度是整个网页分析速度的关键之
O
[0003]处理XPath有多重方式。需要先用语法分析器将文本表达式转换为内存结构,然后使用DOM树模型的XML文档表达并依此查询。但是在网页处理的环境中,这种做法因为内存和速度的关系,效果并不太好。所以之后有人提出了流式XPath的概念:它去除了原来XPath中定义的部分后退等元素,使得XPath的分析可以以一种一次扫描而不必来回移动的方式进行,所以速度得到了巨大的提高。流式XPath通常和SAX的XML模型结合工作,SAX模型不必建立内存节点,是一次遍历的方式。速度更快,在这次遍历工作中一边分析XML元素,一边处理XPath。这样来实现流式XPath的规范要求。
[0004]严重依赖SAX分析因不同的SAX引擎而有不同的效果。但是在大部分情况下无法知道一个SAX引擎是否针对以下情况进行优化:1.同时分析多条XPath。2.错误检测和错误恢复。3.跳过不必要的分析。其中第I点需要XPath分析器使用数据结构处理,第2点根据不同的SAX引擎有不同的效果。SAX通常的做法是对所有的节点都进行分析处理,然后使用回调函数通知上层。上层根据节点名称选择性的处理,不需要的节点就丢弃不处理。所以上面的第3点是无论如何也做不到的。
【发明内容】
[0005]为了克服现有技术中的缺陷,本发明提供一种基于期望列表的网页内容抽取方法,提出期望列表的概念。该概念主要描述我们需要什么内容,就去查询它,如果不需要这个内容,可以放心的忽略它。这实际上是受到人类自身处理XML的启发,如果要我们自身拿着XPath结构去分析一个XML文件。那么我们自然也是一层一层的去查询它,查到第一层才会去想查询第二层。到此为止都和机器处理是一样的,但是我们能够跳过不需要的内容。例如我们查询的XPath不包含任何属性内容,那么我们自然不需要去注意XML节点的属性。这样的唯一好处就是能够加速分析。
[0006]本发明期望列表的完整内容包含三方面的内容:
[0007]1.不使用结构化分析工具,仅仅使用字符串查找方式;
[0008]2.使用期望状态机来指挥分析工作;
[0009]3.使用期望列表来表达查询状态。
[0010]具体技术方案为:
[0011]一种基于期望列表的网页内容抽取方法,包括以下步骤:[0012]a.一开始,将状态设置为 PARSE_BEGIN(b);
[0013]b.在PARSE_BEGIN中,清理所有列表的内容,准备进行新一轮的分析,并将所有XPath链表的第一个节点加入期望列表中,并将状态设置为PARSE_TAG_BEG(c);
[0014]c.在PARSE_TAG_BEG中,查找第一个出现的'夕字符,并根据条件转到相应的状态:
[0015]如果开头是〈!一,表明此节点是注释节点,转到PARSE_C0MMENT-BEG(1),
[0016]如果开头是〈/,则出栈并转入到PARSE_CHILD_TEXT(i)状态.表明一个子节点的结束,
[0017]如果开头是〈!**,表明此节点是动作节点,不必分析,则转入PARSE_IGN0RE(j)状态,
[0018]默认转到PARSE_TAG 状态(d);
[0019]d.在PARSE_TAG状态中,扫描出一个不以空格'/'结束的字符串.并且查找期望列表中是否有匹配的项.如果有则看有没有下一个XPath节点.没有的话则表示查找完成.通知上层有结果.有的话则把下一个节点加入期望列表,
[0020]另外根据期望列表中是否要求处理属性来决定转移是到PARSE_ATTR_BEG(f)还是PARSE_TAG_END(e);
[0021]e.在PARSE_TAG_END中,扫描到'X字符.然后执行step_in操作.期望列表入栈,表明进入一个子节点.并转移到PARSE_CHILD_TEXT(i)状态;
.[0022]f.在 PARSE_ATTR_BEG 状态直接转移到 PARSE_ATTR (g)状态;
[0023]g.在PARSE_ATTR状态中如果出现,>'则转为PARSE_ATTR_END (h).否则继续扫描一个属性,状态不变;
[0024]h.在PARSE_ATTR_END状态中,清理临时变量,并转为PARSE_TAG_END (e)状态;
[0025]1.在PARSE_CHILD_TEXT状态中,扫描到'〈'符号为止,中间的内容就是文本节点,查看是否有合适的文本搜集器,并转为PARSE_TAG_BEG(c)状态;
[0026]j.在PARSE_IGN0RE状态中,扫描到'V符号为止,并直接转为PARSE_TAG_BEG(c)状态;
[0027]k.在PARSE_PASS状态中,扫描到匹配的'〈[tag]'字符串,并转为PARSE_TAG_BEG(c)状态;
[0028]1.在 PARSE_COMMENT_BEG_PARSE_COMMENT PARSE_COMMENT_END 中扫描出一个<!——> 标签,并转为PARSE_TAG_BEG (c)状态;
[0029]η.当扫描到文本的最后,停止扫描,分析完成。
[0030]本发明的有益效果:
[0031 ] 本发明在PARSE_TAG状态根据期望列表的内容可以选择性的处理属性.目前只是配置了跳过属性的分析,另外根据简单的分析,属性大约占了整个网页的50%,所以通过这一步可以获得近乎一倍的加速.[0032]状态之间的转移:例如进入PARSE_TAG_END状态,则表示期望遇到一个’ >’标签符号.所以通过字符串查找函数查找到’ >’符号.并继续转移状态.如果从PARSE_TAG到PARSE_TAG_END,那么中间无论有没有属性,都直接跳过了.[0033]对于错误修正,把那些常见的不规范节点如meta, script等标签放在专门的状态中处理,无论它是不是有错误.都直接掠过.这样就避免的错误检查和错误恢复的相关步骤.【具体实施方式】
[0034]下面结合【具体实施方式】对本发明的技术方案作进一步详细地说明。
[0035]一种基于期望列表的网页内容抽取方法,包括以下步骤:
[0036]a.一开始,将状态设置为 PARSE_BEGIN(b);
[0037]b.在PARSE_BEGIN中,目标是表明一次分析工作的开始,所以清理所有列表的内容,准备进行新一轮的分析,并将所有XPath链表的第一个节点加入期望列表中,并将状态设置为 PARSE_TAG_BEG(c);
[0038]c.在PARSE_TAG_BEG中,目标是找到一个标签的开始。需要查找第一个出现的' <'字符,并根据条件转到相应的状态:
[0039]如果开头是〈!一,表明此节点是注释节点。转到PARSE_cOMMENT_BEG(I),
[0040]如果开头是〈/,则出栈并转到PARSE_CHILD_TEXT(i)状态。表明一个子节点的结束,
[0041]如果开头是〈!**,表明此节点是动作节点,不必分析。则转入PARSE_IGN0RE(j)状态,
[0042]默认转到PARSE_TAG 状态(C);
[0043]d.在PARSE_TAG状态中,目标是识别一个标签的名称。扫描出一个不以‘空格’,
结束的字符串,即为标签名称。并且查找期望列表中是否有匹配的项。如果有则 看有没有下一个XPath节点:没有的话则表示查找完成,将结果返回给库调用者。如果有的话则把下一个节点加入期望列表;
[0044]另外根据期望列表中是否要求处理属性来决定转移是到PARSE_ATTR_BEG(f)还是PARSE_TAG_END(d);
[0045]e.在PARSE_TAG_END中,需要将扫描头指向标签的结束位置,即扫描到'V字符,表示标签的结束。然后执行step_in操作,将期望列表入栈,保存现场状态。进入子节点,并转移到PARSE_CHILD_TEXT(i)状态;
[0046]f.在PARSE_ATTR_BEG状态,执行attr_in过程。创建临时储存区,并直接转移到PARSE_ATTR(g)状态;
[0047]g.在PARSE_ATTR状态的目标是识别一个属性。一个属性是类似key=value的结构,或者是只有key出现。所以需要扫描‘=’和‘空格’以及’>’,并且扫描出前后的key和value的值,并存入储存区。将得到的key值和期望列表进行比对,如果发现有一样的,表明搜索到了结果,同时查看是否有下一个XPath节点,如果没有的话表明整条XPath查询结束。将结果返回给调用者。如果有下一个节点,则将它加入到期望列表中。最后如果出现‘〉’则表明整个标签都查询完了,需要转为PARSE_ATTR_END(h)。否则继续回到PARSE_ATTR(g)状态,扫描下一个属性;
[0048]h.在PARSE_ATTR_END状态中,需要执行attr_out过程,清理临时储存区,并转为PARSE_TAG_END (d)状态;
[0049]1.在PARSE_CHILD_TEXT状态是为了扫描两个节点之间的文本内容,该状态是从PARSE_TAG_END状态到达的,所以已经指向了一个标签的结束了。因此扫描到' <'符号即下一个标签的开始为止,中间的内容就是文本节点,查看是否有合适的文本搜集器\并转为 PARSE_TAG_BEG (c)状态;
[0050]j.在PARSE_IGN0RE状态中,是为了处理一些二义性的标签如<meta>,〈meta / > ;<br>, <br / >。这类不规范的情况本身会破坏XML的树型结构造成错误,所以直接跳过标签。扫描到' >'符号为止,并直接转为PARSE_TAG_BEG(c)状态;因为我们直接跳过了,也就不再需要额外的错误处理了;
[0051]k.在PARSE_PASS状态中,同样是为了跳过〈script〉和〈style〉这种内容格式复杂的标签。和PARSE_IGN0RE不同的是其结束判定不一样。后者之是以‘〉’字符结束,而前者需要扫描到'〈[tag]'标签对应的闭合标签〈/ [tag]〉,并转为PARSE_TAG_BEG(c)状态;
[0052]1.在 PARSE_COMMENT_BEG PARSE_C0MMENT PARSE_COMMENT_END 中扫描出了一个〈!——> 标签,并转为PARSE_TAG_BEG(c)状态;分三个阶段的意义是为了方便以后分析注释用;
[0053]m.当扫描到文本的结束,即停止扫描,分析完成。
[0054]本发明用于快速抽取XML文档的内容。并且可以用于和XML结构相似的HTML网页。因此主要适用环境是网络爬虫,也就是网页抽取功能。本发明可以提供快速的网页处理速度,并且减少内存占用量。同时对网页的一般错误也能够很好的进行容错处理,保证网络爬虫的可靠性。
[0055]同时还可以对配置文件的解析功能提供支持。大型程序的配置文件通常使用XML格式。本发明API简洁,易于编程。能够对项目快速编程提供有力的支持。
.[0056]以上所述,仅为本发明较佳的【具体实施方式】,本发明的保护范围不限于此,任何熟悉本【技术领域】的技术人员在本发明披露的技术范围内,可显而易见地得到的技术方案的简单变化或等效替换均落入本发明的保护范围内。
【权利要求】
1.一种基于期望列表的网页内容抽取方法,其特征在于,包括以下步骤: a.一开始,将状态设置为PARSE_BEGIN(b); b.在PARSE_BEGIN中,清理所有列表的内容,准备进行新一轮的分析,并将所有XPath链表的第一个节点加入期望列表中,并将状态设置为PARSE_TAG_BEG(c); c.在PARSE_TAG_BEG中,查找第一个出现的,夕字符,并根据条件转到相应的状态: 如果开头是〈!一,表明此节点是注释节点,转到PARSE_C0MMENT_BEG(1), 如果开头是〈/,则出栈并转入到PARSE_CHILD_TEXT(i)状态.表明一个子节点的结束, 如果开头是〈!**,表明此节点是动作节点,不必分析,则转入PARSE_IGNORE(j)状态, 默认转到PARSE_TAG状态(d); d.在PARSE_TAG状态中,扫描出一个不以空格'/'结束的字符串.并且查找期望列表中是否有匹配的项.如果有则看有没有下一个XPath节点.没有的话则表示查找完成.通知上层有结果.有的话则把下一个节点加入期望列表, 另外根据期望列表中是否要求处理属性来决定转移是到PARSE_ATTR_BEG(f)还是PARSE_TAG_END(e); e.在PARSE_TAG_END·中,扫描到'V字符.然后执行skp_in操作.期望列表入栈,表明进入一个子节点.并转移到PARSE_CHILD_TEXT(i)状态; f.在PARSE_ATTR_BEG状态直接转移到PARSE_ATTR(g)状态; g.在PARSE_ATTR状态中如果出现,>'则转为PARSE_ATTR_END(h).否则继续扫描一个属性,状态不变; h.在PARSE_ATTR_END状态中,清理临时变量,并转为PARSE_TAG_END(e)状态; 1.在PARSE_CHILD_TEXT状态中,扫描到'<'符号为止,中间的内容就是文本节点,查看是否有合适的文本搜集器,并转为PARSE_TAG_BEG(c)状态; j.在PARSE_IGNORE状态中,扫描到 > 符号为止,并直接转为PARSE_TAG_BEG (c)状态;k.在PARSE_PASS状态中,扫描到匹配的'〈[tag]'字符串,并转为PARSE_TAG_BEG(c)状态; 1.在 PARSE_COMMENT_BEG_PARSE_COMMENT PARSE_COMMENT_END 中扫描出一个〈!——>标签,并转为PARSE_TAG_BEG(c)状态; m.当扫描到文本的最后,停止扫描,分析完成。
【文档编号】G06F17/30GK103440294SQ201310362840
【公开日】2013年12月11日 申请日期:2013年8月16日 优先权日:2013年8月16日
【发明者】王佰玲, 谢虎成, 黄俊恒, 宫名, 刘扬, 詹春燕 申请人:哈尔滨工业大学(威海)