转自:http://www.blogjava.net/lostfire/archive/2006/07/02/56212.html by lostfire
其中备注部分为个人加入的阅读体会,目的为思考和加深印象,仅供参考;谢谢 lostfire
HtmlParser主要靠Node、AbstractNode和Tag来表达Html,因为Remark和Text相对简单,此处就将其忽略了。
- Node是形成树结构表示HTML的基础,所有的数据表示都是接口Node的实现,Node定义了与页面树结构所表达的页面Page对象,定义了获取父、子、兄弟节点的方法,定义了节点到对应html文本的方法,定义了该节点对应的起止位置,定义了过滤方法,定义了Visitor访问机制。
备注:(Node可以认为是树模型中的节点,是节点的行为接口;包括:
1. 以该节点为基础在树模型中游走的行为(包括获取树本身),
2.获取该节点中所含信息的行为;
3.提供关于双方问模式中作为被访问者的accept方法
关于visit模式,参见 链接 visit模式讲解 ;关于visit模式,常见的应用场景包括:外部结构对树结构中对某一个node进行操作,而不是对树所有的node进行操作,等; 自己体会生活中可以看到的访问者模式包括:自助餐厅被访问accept,食客作为visitor; 大型的研讨会,大型的展会,集市等等的行为模拟; 技术上html,xml树结构,其他的容器结构等;)
- AbstractNode是Node的一种具体的类实现,起到构成树形结构的作用,除了同具体Node相关的accept方法,toString,toHtml,toPlainTextString方法以外,AbstractNode实现了大多基本的方法,使得它的子类,不用理会具体的树操作。
备注:(node基本行为的实现,提供的基本抽象node类;)
- Tag是具体分析的主要内容。Tag分成composite的Tag和不能包含其他Tag的简单Tag两类,其中前者的基类是CompositeTag,其子类包含BodyTag,Div,FrameSetTag,OptionTag,等27个子类;而简单Tag有BaseHrefTag、DoctypeTag,FrameTag,ImageTag,InputTag,JspTag,MetaTag,ProcessingInstructionTag这八类。
备注:(继承自Node的接口,强调是一个tag类型的node,一个tag代表HMTL中的一个标签,eg:<xxx yyy="zzz">,行为主要是处理标签的相关行为,如属性处理,id,name获取等)
Node分成三类:
- RemarkNode:代表Html中的注释
- TagNode:标签节点,是种类最多的节点类型,上述Tag的具体节点类都是TagNode的实现。
备注:(parser创建的所有tag的基础类;直接继承于abstractNode和实现了Tag的接口)
- TextNode:文本节点
- 用一个URL或页面String做一个Parser
- 用这个Parser做一个Visitor
- 使用Parser.visitAllNodeWith(Visitor)来遍历节点
- 获取Visitor遍历后得到的数据
- 做解析之前做的事情:visitor.beginParsing();
- 每次取到一个节点Node,让该Node接受accept该Visitor
- 做解析后做的事情:visitor.finishedParsing();
- 对于所有TagNode都使用一个accept方法,即TagNode的accept方法。首先判断是否是标签结尾,如果是就visitor.visitEndTag (this);否则visitor.visitTag (this);
- 如果是TextNode,那就visitor.visitStringNode (this);就可以了。
- 如果是RemarkNode,那就visitor.visitRemarkNode (this);就可以了。
实际上NodeVisitor里边这四种visit方法都是空的,因为在不同的Visitor中对于这三类节点的处理是不同的;对于需要处理的节点,只要重载对应的visit方法就行了,如果不处理那就不理会就可以了;另外,如果用户用自己的Visitor,那么还可以灵活的处理不同类型的节点了。
- ObjectFindingVisitor:用来找出所有指定类型的节点,采用getTags()来获取结果。
- StringBean:用来从一个指定的URL获取移除了<SCRIPT></SCRIPT>和<PRE></PRE>之间代码的Html代码,也可以用做Visitor,用来移除这两种标签内部的代码,采用StringBean.getStrings()来获取结果。
- HtmlPage:提取Title,body中的节点和页面中的TableTag节点。
- LinkFindingVisitor:找出节点中包含某个链接的总个数。
- StringFindingVisitor:找出遍历的TextNode中含有指定字符串的个数。
- TagFindingVisitor:找出指定Tag的所有节点,可以指定多种类型。
- TextExtractingVisitor:从网页中把所有标签去掉来提取文本,这个提取文本的Visitor有时是很实用的,只是注意在提取文本时将标签的属性也去掉了,也就是说只剩下标签之间的文本,例如<a>中的链接也去掉了。
- UrlModifyingVisitor:用来修改网页中的链接。