文章来源:[url]http://blog.sina.com.cn/s/blog_87e88aac01010zf1.html[/url]
虽说很早以前听说过web-harvest 这个东西,但是没有真正的花太多的功夫去研究它,但在最近静下心来去研究一番,才觉得这个东西确实是很方便和强大!大概而言,就是:
1.构建抽取规则简单方便强大
2.可以通过一个xml文件进行规则和抽取逻辑的配置
3.可以在配置文件中进行相关的逻辑判断,很好的支持java语言,当然这要归功于beanshell
4.最大的方便在于,写好程序后,基本就不用修改,每次写一个配置文件就行了!
具体是怎么做的了,这需要通过在java程序中进行调用,而不能依靠web-harvest本身的GUI界面来进行,但官方的文档就简单的提供了几行代码,剩下的就是省略号了,扔下一大堆东西需要自己去摸索,不过还好啦,通过阅读源码和程序的说明,基本上弄懂了,如何在程序层面利用web- harvest去抽取信息,给个简单的示例,大家就知道这个web-harvest就有多么的方便了!不算是一个完整的java程序,但是一个开发的基本的流程,中间有些变量需要改变
private ScraperConfiguration config;
private Scraper scraper;
config = new ScraperConfiguration(context.getRuleConfig());//配置文件的路径
scraper = new Scraper(config, context.getWorkDir());//工作的目录
scraper.addVariableToContext("pagecontent",new String(this.pageContent));//通过程序的方式,将java变量赋值给配置文件中的变量,呵呵,方便吧!注意要new Sting()下
scraper.addVariableToContext("linkurl",new String(""));
scraper.setDebug(false);
scraper.execute();//真正的开始执行
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- config for www.qianzhihe.com.cn -->
<config charset="gb2312">
<!-- raw content of page define in java -->
<!-- define linkurl 一个变量,通过java程序的方式赋值-->
<var name="linkurl"></var>
<!-- to decide link is product or not 下面使用了强大的脚本beanshell语言,实际就是java语言,-->
<var-def name="isproductlink">
<script return="islinkproduct"><![CDATA[
islinkproduct=linkurl.toString().matches("http://www.qianzhihe.com.cn/Product/[0-9]+.htm");
]]></script>
</var-def>
<!-- to decide link is pagelist or not -->
<var-def name="isproductlist">
<script return="islistproduct"><![CDATA[
islistproduct=false;
if(linkurl.toString().contains("tsort.asp") || linkurl.toString().contains("pinpai.asp")){
islistproduct=true;
}
]]></script>
</var-def>
<!-- convert to xml 注意其中的变量pagecontent,也是通过java的方式赋值过来的-->
<var-def name="xmlcontent">
<html-to-xml specialentities="false">
<var name="pagecontent"></var>
</html-to-xml>
</var-def>
<!-- to get product title 解释下xpath语法吧,这个是获取带有属性名class并且其属性值是vtitle的标签为td中的内容 -->
<empty>
<var-def name="name">
<xpath expression="data(//td[@class='vtitle'])">
<var name="xmlcontent"></var>
</xpath>
</var-def>
</empty>
<!-- to get product price 这个语法很好用,就是相当于获取一个数组中的第几个元素了,从所有拥有属性名为color的并且属性值为#D03430的标签名为font的集合中,选取第二个元素的内容 -->
<empty>
<var-def name="rawprice">
<xpath expression="data((//font[@color='#D03430'])[2])">
<var name="xmlcontent"></var>
</xpath>
</var-def>
</empty>
<!-- to get clean price -->
<empty>
<var-def name="price">
<script return="cleanprice"><![CDATA[
cleanprice=rawprice.toString().replaceAll("¥","").replaceAll(",","");
]]></script>
</var-def>
</empty>
<!-- to get product sort -->
<empty>
<var-def name="rawsort">
<xpath expression="data(//td[@class='sort'])">
<var name="xmlcontent"></var>
</xpath>
</var-def>
</empty>
<!-- to get clean sort -->
<empty>
<var-def name="sort">
<script return="cleansort"><![CDATA[
cleansort=rawsort.toString().replaceAll(">>","|").replaceAll(",","");
]]></script>
</var-def>
</empty>
<!-- to get product digest -->
<empty>
<var-def name="digest">
<xpath expression="data(//div[@id='tab1_1'])">
<var name="xmlcontent"></var>
</xpath>
</var-def>
</empty>
<!-- to get page body -->
<empty>
<var-def name="body">
<xpath expression="data(//body)">
<var name="xmlcontent"></var>
</xpath>
</var-def>
</empty>
</config>
至于xpath的详细语法,脚本语言的编写还是请各位去仔细查下资料看看,一下子也很难讲述完整!可以参考:www.w3school.com.cn
到后来怎么获取数据呢?请看下面的简单代码:
就是通过scraper去获取配置文件中的变量,并转化为java中的变量类型就行可以了
Variable title = (Variable) scraper.getContext().get("name");
return title.toString();
在使用完一个scraper之后,要记得释放一些变量,这个是通过scraper.dispose()方法来释放一些变量,要不然会存在一些问题,使用的内存越来越多,最后outofmemory,呵呵!
对于中文的支持也不错,自己在使用过程中没有遇到过乱码,关键是要合理选择好字符集!
虽说很早以前听说过web-harvest 这个东西,但是没有真正的花太多的功夫去研究它,但在最近静下心来去研究一番,才觉得这个东西确实是很方便和强大!大概而言,就是:
1.构建抽取规则简单方便强大
2.可以通过一个xml文件进行规则和抽取逻辑的配置
3.可以在配置文件中进行相关的逻辑判断,很好的支持java语言,当然这要归功于beanshell
4.最大的方便在于,写好程序后,基本就不用修改,每次写一个配置文件就行了!
具体是怎么做的了,这需要通过在java程序中进行调用,而不能依靠web-harvest本身的GUI界面来进行,但官方的文档就简单的提供了几行代码,剩下的就是省略号了,扔下一大堆东西需要自己去摸索,不过还好啦,通过阅读源码和程序的说明,基本上弄懂了,如何在程序层面利用web- harvest去抽取信息,给个简单的示例,大家就知道这个web-harvest就有多么的方便了!不算是一个完整的java程序,但是一个开发的基本的流程,中间有些变量需要改变
private ScraperConfiguration config;
private Scraper scraper;
config = new ScraperConfiguration(context.getRuleConfig());//配置文件的路径
scraper = new Scraper(config, context.getWorkDir());//工作的目录
scraper.addVariableToContext("pagecontent",new String(this.pageContent));//通过程序的方式,将java变量赋值给配置文件中的变量,呵呵,方便吧!注意要new Sting()下
scraper.addVariableToContext("linkurl",new String(""));
scraper.setDebug(false);
scraper.execute();//真正的开始执行
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- config for www.qianzhihe.com.cn -->
<config charset="gb2312">
<!-- raw content of page define in java -->
<!-- define linkurl 一个变量,通过java程序的方式赋值-->
<var name="linkurl"></var>
<!-- to decide link is product or not 下面使用了强大的脚本beanshell语言,实际就是java语言,-->
<var-def name="isproductlink">
<script return="islinkproduct"><![CDATA[
islinkproduct=linkurl.toString().matches("http://www.qianzhihe.com.cn/Product/[0-9]+.htm");
]]></script>
</var-def>
<!-- to decide link is pagelist or not -->
<var-def name="isproductlist">
<script return="islistproduct"><![CDATA[
islistproduct=false;
if(linkurl.toString().contains("tsort.asp") || linkurl.toString().contains("pinpai.asp")){
islistproduct=true;
}
]]></script>
</var-def>
<!-- convert to xml 注意其中的变量pagecontent,也是通过java的方式赋值过来的-->
<var-def name="xmlcontent">
<html-to-xml specialentities="false">
<var name="pagecontent"></var>
</html-to-xml>
</var-def>
<!-- to get product title 解释下xpath语法吧,这个是获取带有属性名class并且其属性值是vtitle的标签为td中的内容 -->
<empty>
<var-def name="name">
<xpath expression="data(//td[@class='vtitle'])">
<var name="xmlcontent"></var>
</xpath>
</var-def>
</empty>
<!-- to get product price 这个语法很好用,就是相当于获取一个数组中的第几个元素了,从所有拥有属性名为color的并且属性值为#D03430的标签名为font的集合中,选取第二个元素的内容 -->
<empty>
<var-def name="rawprice">
<xpath expression="data((//font[@color='#D03430'])[2])">
<var name="xmlcontent"></var>
</xpath>
</var-def>
</empty>
<!-- to get clean price -->
<empty>
<var-def name="price">
<script return="cleanprice"><![CDATA[
cleanprice=rawprice.toString().replaceAll("¥","").replaceAll(",","");
]]></script>
</var-def>
</empty>
<!-- to get product sort -->
<empty>
<var-def name="rawsort">
<xpath expression="data(//td[@class='sort'])">
<var name="xmlcontent"></var>
</xpath>
</var-def>
</empty>
<!-- to get clean sort -->
<empty>
<var-def name="sort">
<script return="cleansort"><![CDATA[
cleansort=rawsort.toString().replaceAll(">>","|").replaceAll(",","");
]]></script>
</var-def>
</empty>
<!-- to get product digest -->
<empty>
<var-def name="digest">
<xpath expression="data(//div[@id='tab1_1'])">
<var name="xmlcontent"></var>
</xpath>
</var-def>
</empty>
<!-- to get page body -->
<empty>
<var-def name="body">
<xpath expression="data(//body)">
<var name="xmlcontent"></var>
</xpath>
</var-def>
</empty>
</config>
至于xpath的详细语法,脚本语言的编写还是请各位去仔细查下资料看看,一下子也很难讲述完整!可以参考:www.w3school.com.cn
到后来怎么获取数据呢?请看下面的简单代码:
就是通过scraper去获取配置文件中的变量,并转化为java中的变量类型就行可以了
Variable title = (Variable) scraper.getContext().get("name");
return title.toString();
在使用完一个scraper之后,要记得释放一些变量,这个是通过scraper.dispose()方法来释放一些变量,要不然会存在一些问题,使用的内存越来越多,最后outofmemory,呵呵!
对于中文的支持也不错,自己在使用过程中没有遇到过乱码,关键是要合理选择好字符集!