首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > CSS >

NekoHTML学习札记

2012-09-17 
NekoHTML学习笔记编译运行如下:outputPage(new FetcherOutput(fle, MD5Hash.digest(response.getContent()

NekoHTML学习笔记

编译运行如下:

outputPage(new FetcherOutput(fle, MD5Hash.digest(response.getContent()), true, title, outlinks), new FetcherContent(response.getContent()), new FetcherText(text)); } private static void getText(StringBuffer sb, Node node) { if (node.getNodeType() == Node.TEXT_NODE) { sb.append(node.getNodeValue());//取得结点值,即开始与结束标签之间的信息 } NodeList children = node.getChildNodes(); if ( children != null ) { int len = children.getLength(); for ( int i = 0; i < len; i++ ) { getText(sb, children.item(i));//递归遍历DOM树 } } }

private static boolean getTitle(StringBuffer sb, Node node) { if (node.getNodeType() == Node.ELEMENT_NODE) { if ("title".equalsIgnoreCase(node.getNodeName())) { getText(sb, node); return true; } } NodeList children = node.getChildNodes(); if (children != null) { int len = children.getLength(); for (int i = 0; i < len; i++) { if (getTitle(sb, children.item(i))) { return true; } } } return false; }

private static void getOutlinks(URL base, ArrayList outlinks, Node node) { if (node.getNodeType() == Node.ELEMENT_NODE) { if ("a".equalsIgnoreCase(node.getNodeName())) { StringBuffer linkText = new StringBuffer(); getText(linkText, node);

NamedNodeMap attrs = node.getAttributes(); String target= null; for (int i= 0; i < attrs.getLength(); i++ ) { if ("href".equalsIgnoreCase(attrs.item(i).getNodeName())) { target= attrs.item(i).getNodeValue();//在DOM树中,属性是一个结点。 break; } } if (target != null) try { URL url = new URL(base, target); outlinks.add(new Outlink(url.toString(),linkText.toString().trim())); } catch (MalformedURLException e) { // don't care } } } NodeList children = node.getChildNodes(); if ( children != null ) { int len = children.getLength(); for ( int i = 0; i < len; i++ ) { getOutlinks(base, outlinks, children.item(i));//递归遍历DOM树 } } } ....}


注意,此处传递给解析过程parse的文档片段对象,必须是由org.w3c.dom.html.HTMLDocument类型的DOM文档对象创建,否则有异常。
  HTMLConfiguration可以用于创建任何基于XNI解析器,可参考下例

package sample;

import org.apache.xerces.parsers.AbstractSAXParser;import org.cyberneko.html.HTMLConfiguration;

public class HTMLSAXParser extends AbstractSAXParser { public HTMLSAXParser() { super(new HTMLConfiguration()); }}

?

三、设置解析器参数

  为了更加精确的控制解析的动作,nekohtml提供了相应的设置函数。如下列:

// settings on HTMLConfigurationorg.apache.xerces.xni.parser.XMLParserConfiguration config =  new org.cyberneko.html.HTMLConfiguration();config.setFeature("http://cyberneko.org/html/features/augmentations", true);config.setProperty("http://cyberneko.org/html/properties/names/elems", "lower");

// settings on DOMParserorg.cyberneko.html.parsers.DOMParser parser = new org.cyberneko.html.parsers.DOMParser();parser.setFeature("http://cyberneko.org/html/features/augmentations", true);parser.setProperty("http://cyberneko.org/html/properties/names/elems", "lower");

?

nekohtml功能(feature)列表
功能默认值描述http://cyberneko.org/html/features/balance-tags True是否允许增补缺失的标签。如果要以XML方式操作HTML文件,此值必须为真。此处提供设置功能,为了性能的原因。http://cyberneko.org/html/features/balance-tags/ignore-outside-content False是否忽略文档根元素以后的数据。如果为false,<html>和<bod>被忽略,所有的内容都被解析。http://cyberneko.org/html/features/document-fragment False解析HTML片段时是否作标签增补。此功能不要用在DOMParser上,而要用在DOMFragmentParser上。http://apache.org/xml/features/scanner/notify-char-refs False当遇到字符实体引用(如&#x20;)是否将(#x20)报告给相应地文档处理器。http://apache.org/xml/features/scanner/notify-builtin-refs False当遇到XML内建的字符实体引用(如&amp;)是否将(amp)报告给相应地文档处理器。http://cyberneko.org/html/features/scanner/notify-builtin-refs False当遇到HTML内建的字符实体引用(如&copy;)是否将(copy)报告给相应地文档处理器。http://cyberneko.org/html/features/scanner/script/strip-comment-delims False是否剥掉<script>元素中的<!-- -->等注释符。http://cyberneko.org/html/features/augmentations False是否将与HTML事件有关的infoset项包括在解析管道中。http://cyberneko.org/html/features/report-errors False是否报告错误。
nekohtml属性列表
属性默认值值域描述http://cyberneko.org/html/properties/filters nullXMLDocumentFilter[] 在解析管道的最后按数组顺序追加自定义的处理组件(过滤器),必须为数组类型。http://cyberneko.org/html/properties/default-encoding Windows-1252IANA encoding names默认的HTML文件编码http://cyberneko.org/html/properties/names/elems upperupper,lower,match如果整理识别出的元素名称http://cyberneko.org/html/properties/names/attrs lowerupper,lower,no-change如果整理识别出的属性名称

?

四、管道过滤器


  Xerces Native Interface (XNI)定义了一个解析器配置框架,在那儿一个个解析器以模块化组件的形式组成一个管道。这样一来,通过重新安排已有组件和/或新定制开发的组件,就可完成一个新的解析器配置工作。由于nekohtml是采用这个配置框架开发的,所以对解析器新增功能就很简单通过在默认的nekohtml解析管道的末端增加文档过滤器来实现。
  要新开发一个过滤器,很简单地实现xerces2的org.apache.xerces.xni.parser包中的XMLDocumentFilter接口即可。这个接口,一方面使组件成为管道中上一级的事件处理器,另一方面又成为下级的信息源。针对nekohtml的过滤器开发,只需简单地扩展org.cyberneko.html.filters包中的DefaultFilter类即可。
  将自行开发的过滤器加入管道,可参考以下两种办法:

XMLDocumentFilter noop = new DefaultFilter();XMLDocumentFilter[] filters = { noop };

XMLParserConfiguration parser = new HTMLConfiguration();parser.setProperty("http://cyberneko.org/html/properties/filters", filters);


  nekohtml的org.cyberneko.html.filters 包中有DefaultFilter、
ElementRemover、Identity、Writer,能实现动态插入内容、删除元素、序列化HTML文档等,不详细述。

热点排行
Bad Request.