这个有“标题党”之嫌了。名字但是像模像样。关于网页爬虫(就是抓取网页内容)的小工具大家都写过吧。可是一般写这样的东西都是类似完成某个简单的需求而 写的类似脚本语言的东西,一般代码不多,类似黑客程序代码风格。大家应该没有做过大型项目全部以抓取网页内容为数据源吧?我就做过这样的项目,呵呵。
如果真是一个多人合作,周期较长,又是一个产品型的项目,需要维护,升级,那代码就不是一次性的了。得有点企业开发的代码风格。
如果数据源都是要从网页抓取的话,开发就很装简单了,先通过URLConnection之类的api得到网页内容,再用正则表达式分析出里面有用的内容。 就这么简单。可是如果是一个项目,页面上千个,而且,还有而且哦,而且别人的网页格式可能会变,布局会变,举个例子,假如一段html是<td class="tig">user001</td>,现在改成了<li>user001</li>,有用的数 据"user001"没有变,可是样式变了。这时候如果还要改代码的话是不是要在代码改正则表达式了。
这时我们就需要一个这样的功能组件,可以把某段html代码里有用的信息抽取出来,转成我们可以操作的业务bean对象。
而且这个抽取规则是可配置的,而不是硬编码在代码里。就像这样的配置文件:
1 <html2javaConfig>2 3 <bean id="user1"class="com.googlecode.html2javabean.client.User">4 5 <property name="name"groupIndex="1">6 7 <![CDATA[8 9 <span id="lblName">(.*?)</span>
10 11 ]]>12 13 </property>14 15 <property name="code">16 17 <![CDATA[18 19 <span id="lblWork">(.*?)</span></td>
20 21 ]]>22 23 </property>24 25 <property name="isMan">26 27 <![CDATA[28 29 <span id="lblSex">(.*?)</span></td>
30 31 ]]>32 33 </property>34 35 </bean>36 37 </html2javaConfig>
要抽取的html文件如下 :
1 <table style="height: 306px; 99%;">2 3 <tr>4 5 <th style=" 100px;"align="left">6 7 姓名:</th>8 9 <td>10 11 <span id="lblName">tony</span>12 13 </td>14 15 </tr>16 17 <tr>18 19 <th align="left">20 21 员工编号:</th>22 23 <td>24 25 <span id="lblWork">ite00395</span></td>26 27 </tr>28 29 <tr>30 31 <th align="left">32 33 性别:</th>34 35 <td>36 37 <span id="lblSex">man</span></td>38 39 </tr>40 41 <tr>42 43 <th align="left">44 45 Email:</th>46 47 <td>48 49 <span id="lblEmail">lihf@gggg.com</span>50 51 </td>52 53 </tr>54 55 <tr>56 57 <th align="left">58 59 MSN:</th>60 61 <td>62 63 <span id="lblMsn">lhf@hotmail.com</span></td>64 65 </tr>66 67 <tr>68 69 <th align="left">70 71 公司电话:</th>72 73 <td>74 75 <span id="lblPhone"></span></td>76 77 </tr>78 79 <tr>80 81 <th align="left">82 83 移动电话:</th>84 85 <td>86 87 <span id="lblMobile">13714896419</span></td>88 89 </tr>90 91 <tr>92 93 <th align="left">94 95 所属部门:</th>96 97 <td valign="middle">98 99 <span id="lblDepartment">P后台项目组</span></td>100 101 </tr>102 103 <tr>104 105 <th align="left">106 107 部门地址:</th>108 109 <td valign="middle">110 111 <span id="lblDeptAddress"></span></td>112 113 </tr>114 115 </table>
最终转成的javabean对象如下:
publicclassUser implementsSerializable{
/**
* serialVersionUID
*/privatestaticfinallongserialVersionUID =5014957386430143870L;
privateString name;
privateString code;
privatebooleanisMan;
privateString email;
privateString msn;
publicString getName() {
returnname;
}
publicvoidsetName(String name) {
this.name =name;
}
publicString getCode() {
returncode;
}
publicvoidsetCode(String code) {
this.code =code;
}
publicbooleanisMan() {
returnisMan;
}
publicvoidsetMan(booleanisMan) {
this.isMan =isMan;
}
publicString getEmail() {
returnemail;
}
publicvoidsetEmail(String email) {
this.email =email;
}
publicString getMsn() {
returnmsn;
}
publicvoidsetMsn(String msn) {
this.msn =msn;
}
}
这样就可以用以下的代码调用这个组件了:
publicvoidtestParse() throwsIOException{
String resource ="h2j_config.xml";
Reader reader =Resources.getResourceAsReader(resource);
Html2JavabeanClient client =Html2JavabeanClientBuilder.buildSqlMapClient(reader);
StringWriter sw =newStringWriter();
InputStream is =Resources.getResourceAsStream("oneuser.html");
BufferedReader reader1 =newBufferedReader(newInputStreamReader(is));
String temp =null;
while((temp =reader1.readLine()) !=null){
sw.write(temp);
}
reader1.close();
User u =(User)client.parseForObject("user1", sw.getBuffer().toString());
System.out.println(u.getName() +""+u.getCode());
}
感觉使用起来很像ibatis是吧,因为我这个组件就是拿的ibatis里解析xml的代码改的,学习ibatis源码的时候有了这个想法。
如果有人遇到这种情况的项目不得不解析很多html的话,这种组件想法还是不错的。有需要的可以参考下我写的代码,然后自己写个,我的代码其其实没有写完,只是实验性的做了个demo。如果需要交流的可以email我。
又想起了广州岑村高科和那帮兄弟一起的日子。
项目代码地址:
http://code.google.com/p/html2javabean/