前述:前几天看到有人论要请别人写一个从从网页上抓取某个专利号的收费信息的一个程序,说实话我自己知道那里面的原理是什么,但一直没有自己动手实现以下。根据自己的实际的工作需要一般是有一张Excel表,第一列是很多的专利号,如果需要将自己查的信息保存起来,可以用数据库,但我想借此来了解一下开源的那些读写Excel表的框架的功能,所以想从Excel表中读取我想要的专利号,然后再写到一个Excel文件中去。于是就要了下面的内容。

准备分成两部分,第一部分写如如何从网页上抓数据。第二部写读写Excel表的实现

在这里事先说明,因为自己也是第一次使用,编码和说辞之处肯定会有很多不成熟的地方,希望路过的高手能不吝赐教,如果想利用这个来学习其里面深层次的原理,那还是跳过哦这里,这里的东西很粗糙的。如果你觉得我写的东西存在误导性的言论,那么请你一定要一针见血的指出来,自己很菜,所以很害怕自己写的东西会误导一些刚入门的编程爱好者……


首先是进入一个专利查询的网站,比如×××网站

收费信息查询:http://app.sipo.gov.cn:8080/searchfee/searchfee.jsp

根据专利号到专利查询的网站上抓取想要的信息(上)_爱好者

在输入框中输入你要查询的专利号,如2011205697907

此时可以启动浏览器的开发人员工具,这里以火狐为例,按住F12进入FireBug的界面,进入网络的选项

根据专利号到专利查询的网站上抓取想要的信息(上)_数据库_02

然后点击收费信息查询的按钮,可以看到页面向服务器传送的请求信息

根据专利号到专利查询的网站上抓取想要的信息(上)_数据库_03

从页面中得到的主要信息就是你发送的是Post的请求,因为是post信息,其请求的参数并不会在地址栏中显示,这个时候可以点击头信息右边的Post信息,可以看到起具体传送的参数信息,该例子的信息显示如下

根据专利号到专利查询的网站上抓取想要的信息(上)_数据库_04

综上其发送的头信息是http://app.sipo.gov.cn:8080/searchfee/searchfee.jsp

Post参数sqh = 2011205697907

所以到此我们已经知道了其发送请求的具体形式了。下面的问题是如何从我得到的网页上得到自己想要的收费信息呢?

根据专利号到专利查询的网站上抓取想要的信息(上)_专利号_05

首先可以做的是查看网页的HTML代码,这些显示的信息无非就是一些

<table><thead><tr><td>之类的标签

  <tr bgcolor="#f4f3f3">
    <td  align="center" class="zi_06"> 申请号</td>
    <td height="26" align="center" class="zi_06"> 费用金额</td>
 <td  align="center" class="zi_06"> 费用种类</td>
    <td  align="center" class="zi_06"> 挂号号</td>
    <td  align="center" class="zi_06"> 收据号</td>
    <td  align="center" class="zi_06">缴费人信息</td>
    <td  align="center" class="zi_06">处理状态</td>
    <td  align="center" class="zi_06">缴费日</td>
    <!--td  align="center" class="zi_06">收据发文日</td-->
  </tr>
                                                                                                                                         
  <tr onMouseOver="this.className='td-over'" onMouseOut="this.className='td-out'">
<td height="27" class="dixian1" align="center"> 201120569790.7</td>
    <td height="27" class="dixian1" align="center"> 150</td>
    <td height="27" class="dixian1" align="center"> 实用新型专利申请费</td>
    <td height="27" class="dixian1" align="center"> </td>
    <td height="27" class="dixian1" align="center"> 23151705</td>
    <td height="27" class="dixian1" align="center"> 湘能华磊光电股份有限公司</td>
    <td height="27" class="dixian1" align="center"> 处理结束</td>
    <td height="27" class="dixian1" align="center"> 2012.02.01</td>
    <!--td height="27" class="dixian1" align="center"> 2012.02.03</td-->
  </tr>

解决方案

1、利用正则表达式,先设置好我要查询信息的格式,将符和这些格式的信息挑出来

2、利用开源的抓取网页信息的jar包,也是我做实际上选用的方式,这里我用的是jsoup-1.7.3.jar可以到下面的网址下载最新的版本,或者在本文附件下载

http://jsoup.org/download

利用jsoup 在我看来是一个强大的抓取网页的工具,其里面还封装了java.net.*包下的类,所以对于我们发送各种网络上的请求接收请求也是十分方便的,当然你也可以用java原生态的java.net.*下的类进行处理,在这里不再赘述。废话不说了,赶紧上代码

public void getFeiInfo(String sqid) throws IOException{
        //发送请求Jsoup的静态方法connect,参数是我们要请求的头信息,返回的是Connection对象,
        //connection对象的静态方法date()用于包装请求的参数,我们这里要加的是sqh,返回的仍然是是Connection对象
        //然后是发送信息,调用Connection的post()方法     (此外还有get()方法,详细的信息可以查看jsoup的docs)
        //post()方法返回的是Document对象
        Document doc = Jsoup.connect("http://app.sipo.gov.cn:8080/searchfee/searchfee_action.jsp").data("sqh", sqid).post();
        //上面的一行也可以用下面的几行代码替换
        //Connection conn = Jsoup.connect("http://app.sipo.gov.cn:8080/searchfee/searchfee_action.jsp");
        //conn = conn.data("sqh", sqid);
        //Document doc = conn.post();
        //得到<tr>标签的类容,select()是类似一个选择器的东西,(".zi_06")表示选择class = zi_06的tr标签
        Elements heads = doc.getElementsByTag("tr").select(".zi_06");
        for (Element element : heads) {
            System.out.print(element.text()+"\t");
        }
        System.out.println();
        //下面的原理和上面的一致,至于为什么两个select()的参数不一样是因为我要要选择的内容不同
        //上面的是显示表头信息,下面的是显示表头之下的具体收费信息了
        Elements info = doc.getElementsByTag("tr").select(".dixian1");
        int i = 0;
        for (Element element : info) {
            i++;
            System.out.print(element.text()+"\t");
            //因为我知道这个表格只有8列
            if(8==i){
                System.out.println();
                i=0;
            }
        }
                                                                                                                                           
    }


然后用个main方法现在控制台中将显示的信息打印出来(见类的细节就不说了

public static void main(String[] args) {
    WebpageCapture wc = new WebpageCapture();
    try {
        wc.getFeiInfo("2011205697907");
    } catch (Exception e) {
        e.printStackTrace();
    }
}


显示的结果如下

申请号     费用金额    费用种类    挂号号     收据号    缴费人信息   处理状态    缴费日
201120569790.7  150     实用新型专利申请费       23151705    湘能华磊光电股份有限公司    处理结束    2012.02.01
201120569790.7  180     实用新型专利第3年年费         26703465    湘能华磊光电股份有限公司    处理结束    2013.02.01
201120569790.7  200     实用新型专利登记印刷费         26703465    湘能华磊光电股份有限公司    处理结束    2013.02.01
201120569790.7  5   印花税         26703465    湘能华磊光电股份有限公司    处理结束    2013.02.01
201120569790.7  1000    恢复权利请求费         26703465    湘能华磊光电股份有限公司    处理结束    2013.02.01
201120569790.7  180     实用新型专利第6年年费         30382557    刘佳丽     处理结束    2014.01.05

反正需要的信息都已经抓下来了,下一步要做的就是将这些抓到的数据写到Excel表中,今天先整理到这了。


根据专利号到专利查询的网站上抓取想要的信息(上) 根据专利号到专利查询的网站上抓取想要的信息(上)