HtmlParser快速入手_学习笔记[转]

1 HtmlParser快速入手_学习笔记
一,数据组织分析:
HtmlParser主要靠Node、AbstractNode和Tag来表达Html,因为Remark和Text相对简单,此处就将其忽略了。

Node 是形成树结构表示HTML的基础,所有的数据表示都是接口Node的实现,Node定义了与页面树结构所表达的页面Page对象,定义了获取父、子、兄弟 节点的方法,定义了节点到对应html文本的方法,定义了该节点对应的起止位置,定义了过滤方法,定义了Visitor访问机制。
AbstractNode 是Node的一种具体的类实现,起到构成树形结构的作用,除了同具体Node相关的accetp方法,toString,toHtml, toPlainTextString方法以外,AbstractNode实现了大多基本的方法,使得它的子类,不用理会具体的树操作。
Tag 是具体分析的主要内容。Tag分成composite的Tag和不能包含其他Tag的简单Tag两类,其中前者的基类是CompositeTag,其子类 包含BodyTag,Div,FrameSetTag,OptionTag,等27个子类;而简单Tag有BaseHrefTag、 DoctypeTag,FrameTag,ImageTag,InputTag,JspTag,MetaTag, ProcessingInstructionTag这八类。
Node分成三类:

RemarkNode:代表Html中的注释
TagNode:标签节点,是种类最多的节点类型,上述Tag的具体节点类都是TagNode的实现。
TextNode:文本节点

二,Visitor方式访问Html:

1,整体解析过程
用一个URL或页面String做一个Parser
用这个Parser做一个Visitor
使用Parser.visitAllNodeWith(Visitor)来遍历节点
获取Visitor遍历后得到的数据
2,Visit过程
做解析之前做的事情:visitor.beginParsing();
每次取到一个节点Node,让该Node接受accept该Visitor
做解析后做的事情:visitor.finishedParsing();
3,获取节点的过程:逐步遍历Html,分析出Node。此部分较为复杂,且对于我们应用来说无需很多了解,暂跳过。

4,节点访问
节点访问采用Visitor模式,Node的accept方法和具体Visitor的visit方法是关键。
首先三类Node来accept的方式各不相同:
对于所有TagNode都使用一个accept方法,即TagNode的accept方法。首先判断是否是标签结尾,如果是就visitor.visitEndTag (this);否则visitor.visitTag (this);
如果是TextNode,那就visitor.visitStringNode (this);就可以了。
如果是RemarkNode,那就visitor.visitRemarkNode (this);就可以了。

实 际上NodeVisitor里边这四种visit方法都是空的,因为在不同的Visitor中对于这三类节点的处理是不同的;对于需要处理的节点,只要重 载对应的visit方法就行了,如果不处理那就不理会就可以了;另外,如果用户用自己的Visitor,那么还可以灵活的处理不同类型的节点了。

系 统为我们实现了下面我要介绍的8种Visitor,实际上可以看作是系统给我们演示了如何做各种各样的Visitor来访问Html,因为实际上我们要真 正来用HtmlParser的话,还需要特定的Visitor,而通过简单的这些系统提供的Visitor组合是难以做成什么事情的。

三,系统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:用来修改网页中的链接。
四,Filter

如果说visitor是遍历提取信息,当然这个信息可以包括某些节点或者从节点分析出来的更有效的信息,这都取决于我们的Visitor做成什么样子,那么Filter则目标很明确,就是用来提取节点的。所以说要想用HtmlParser,首先要熟悉上面讲到的数据组织。

系统定义了17种具体的Filter,包括依据节点父子关系的Filter,连接Filter组合的Filter,依据网页内容匹配情况的filter,等等。我们也可以implement Filter来做自己的Filter来提取节点。

Filter的调用是同Visitor独立的,因为也无需先filter出一些NodeList,再用Visitor来访问。调用Filter的方法是:
NodeList nodeList = myParser.parse(someFilter);
解析之后,我们可以采用:
Node[] nodes = nodeList.toNodeArray();
来获取节点数组,也可以直接访问:
Node node = nodeList.elementAt(i)来获取Node。

另 外,在Filter后得到NodeList以后,我们仍然可以使用NodeList的extractAllNodesThatMatch (someFilter)来进一步过滤,同时又可以用NodeList的isitAllNodesWith(someVisitor)来做进一步的访问。
这 样,我们可以看到HtmlParser为我们提供了非常方便的Html解析方式,针对不同的应用可以采用visitor来遍历Html节点提取数据,也可 以用Filter来过滤节点,提取出我们所关注的节点,再对节点进行处理。通过这样的组合,一定能够找出我们所需要的信息。
2使用Htmlparser解析html(2)_学习笔记
 
import java.io.InputStream;
import java.util.Properties;

import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.tags.TableColumn;
import org.htmlparser.tags.TableRow;
import org.htmlparser.tags.TableTag;

/**
* @author lanxincao
*
*/
public final class HtmlResumeCore {
/**
* HTML格式简历文件位置
*/
private String url="";
/**
* 所使用的模板文件
*/
private String template="";
/**
* 无参构造
*/
public HtmlResumeCore(){

}
/**
* 在指定表中查找指定行、指定列的值
* @param tableid 需解析表ID
* @param row 行号
* @param col 列号
* @return 指定行号、列号的值,出错时返回空字符串
*/
public String getValue(int tableid,int row,int col){
try {
Parser parser = new Parser(url);
parser.setEncoding("GBK");
Node[] nodes = parser.extractAllNodesThatAre(TableTag.class);
if(nodes.length<tableid)return "";
TableTag table = (TableTag)nodes[tableid];
TableRow[] rows = table.getRows();
if(rows.length<row)return "";
TableColumn[] cols = rows[row].getColumns();
if(cols.length<col)return "";
return cols[col].toPlainTextString();
} catch (Exception e) {
System.out.println(e.toString());
return "";
}

}
/**
* 设置需要处理的简历地址url
* @param url
*/
public void setUrl(String url){
this.url = url;
}
public static void main(String args[]){
HtmlResumeCore resume = new HtmlResumeCore();
String url = "c://12.html";
resume.setUrl(url);
resume.setTemplate("1");
System.out.println(resume.getName());
System.out.println(resume.getAge());
System.out.println(resume.getSex());
System.out.println(resume.getXueli());
System.out.println(resume.getPro());
System.out.println(resume.getEmail());
System.out.println(resume.getPhone());
System.out.println(resume.getIdCode());
System.out.println(resume.getPos());
}
/**
* 根据模板序号,获得模板文件
* @param tempid 模板序号
* @return 模板文件
*/
public void setTemplate(String tempid){
Properties properties = new Properties();
try{
InputStream fis = HtmlResumeCore.class.getResourceAsStream("/com/jfcgf/hrms/recruitment/tempid.properties");
properties.load(fis);
template = properties.getProperty(tempid);
}catch(Exception e){
System.out.println("初始化模板文件时发生异常");
}
}
/**
* 要模板中查找位置
* @param key 所需查找的字符串
* @return String 位置
*/
public String getKeyValue(String key){
Properties properties = new Properties();
try{
InputStream fis = HtmlResumeCore.class.getResourceAsStream(template);
properties.load(fis);
return properties.getProperty(key);
}catch(Exception e){
System.out.println("处理模板时发生异常");
return "";
}
}
/*
* 取得姓名
* @return String 姓名
*/
public String getName(){
String[] namelocate = getKeyValue("name").split(",");
int tableid = Integer.parseInt(namelocate[0]);
int rowid = Integer.parseInt(namelocate[1]);
int colid = Integer.parseInt(namelocate[2]);
return getValue(tableid,rowid,colid);
}
/**
* 取得年龄
* @return int 年龄,根据实际情况,此值不大于99
*/
public int getAge(){
String[] namelocate = getKeyValue("age").split(",");
int tableid = Integer.parseInt(namelocate[0]);
int rowid = Integer.parseInt(namelocate[1]);
int colid = Integer.parseInt(namelocate[2]);
String ageString = getValue(tableid,rowid,colid);
return Integer.parseInt(ageString.substring(0,2));
}
/**
* 取得性别
* @return String 性别
*/
public String getSex(){
String[] namelocate = getKeyValue("sex").split(",");
int tableid = Integer.parseInt(namelocate[0]);
int rowid = Integer.parseInt(namelocate[1]);
int colid = Integer.parseInt(namelocate[2]);
return getValue(tableid,rowid,colid);
}
/**
* 取得学历,根据实际情况,此处返回的值只是教育经历中的第一行
* @return String 学历
*/
public String getXueli(){
String[] namelocate = getKeyValue("xueli").split(",");
int tableid = Integer.parseInt(namelocate[0]);
int rowid = Integer.parseInt(namelocate[1]);
int colid = Integer.parseInt(namelocate[2]);
return getValue(tableid,rowid,colid);
}
/**
* 取得应聘者所学专业
* @return String 专业
*/
public String getPro(){
String[] namelocate = getKeyValue("pro").split(",");
int tableid = Integer.parseInt(namelocate[0]);
int rowid = Integer.parseInt(namelocate[1]);
int colid = Integer.parseInt(namelocate[2]);
return getValue(tableid,rowid,colid);
}
/**
* 取得电子邮件地址
* @return String email
*/
public String getEmail(){
String[] namelocate = getKeyValue("email").split(",");
int tableid = Integer.parseInt(namelocate[0]);
int rowid = Integer.parseInt(namelocate[1]);
int colid = Integer.parseInt(namelocate[2]);
String emailString = getValue(tableid,rowid,colid);
if(emailString.indexOf("&")>0)return emailString.substring(0,emailString.indexOf("&"));
return emailString;
}
/**
* 取得联系电话
* @return String 联系电话
*/
public String getPhone(){
String[] namelocate = getKeyValue("phone").split(",");
int tableid = Integer.parseInt(namelocate[0]);
int rowid = Integer.parseInt(namelocate[1]);
int colid = Integer.parseInt(namelocate[2]);
String phoneString = getValue(tableid,rowid,colid);
if(phoneString.indexOf("&")>0)return phoneString.substring(0,phoneString.indexOf("&"));
return phoneString;
}
/**
* 取得身份证号码
* @return String 身份证号码
*/
public String getIdCode(){
String[] namelocate = getKeyValue("idcode").split(",");
int tableid = Integer.parseInt(namelocate[0]);
int rowid = Integer.parseInt(namelocate[1]);
int colid = Integer.parseInt(namelocate[2]);
return getValue(tableid,rowid,colid);
}
/**
* 取得应聘职位
* @return String 职位
*/
public String getPos(){
String[] namelocate = getKeyValue("pos").split(",");
int tableid = Integer.parseInt(namelocate[0]);
int rowid = Integer.parseInt(namelocate[1]);
int colid = Integer.parseInt(namelocate[2]);
return getValue(tableid,rowid,colid);
}
}
3使用Htmlparser解析html(5)_学习笔记
 
HTMLParser
is a super-fast real-time parser for real-world HTML. 他一起设计的简单性,分析实时web页面的高速性来吸引开发者和使用者.
HTMLParser 一个解析web页面的开源类库, 他有两种主要使用方式, extraction和transformation. 前者就是从网页中萃取出你要的东西,后者就是把web页面中的一些内容改为(转换为)你想要的格式. 下面来看看这两种使用情况的各自特点.
Extraction
萃取例如下面的几种常见的使用方式:
* text extraction, 萃取web页面中的文本文字
* link extraction,萃取web页面中的连接 包括url 和 email地址, 还可以自定义其他标签
* screen scraping, 抓去web页面内容
* resource extraction, 萃取web页面中的资源, 图片 , 声音文件......
* a browser front end, the preliminary stage of page display
* link checking, 确保连接是有效的
* site monitoring, 检查web页面的更改
使用一下几种机制来帮助你实现上面的功能:
filters, visitors and JavaBeans
Transformation
处理web页面的内容, 转换为你需要的.包含:
* URL rewriting, 更改一个web页面的部分连接or 全部连接为你想要的.
* site capture, 把远程的网站抓取到本地
* censorship, 检查web页面内容,移出你不想要的字词
* HTML cleanup, 整理html格式,
* ad removal, 过滤广告连接
* conversion to XML, 转换为xml格式的数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值