• 使用java开源工具httpClient及jsoup抓取解析网页数据


    今天做项目的时候遇到这样一个需求,需要在网页上展示今日黄历信息,数据格式如下

    •   公历时间:2016年04月11日 星期一
    •   农历时间:猴年三月初五
    •   天干地支:丙申年 壬辰月 癸亥日
    •   宜:求子 祈福 开光 祭祀 安床
    •   忌:玉堂(黄道)危日,忌出行

      主要包括公历/农历日期,以及忌宜信息的等。但是手里并没有现成的数据可供使用,怎么办呢?

    革命前辈曾经说过,没有枪,没有炮,敌(wang)人(luo)给我们造!网络上有很多现成的在线

    万年历应用可供使用,虽然没有现成接口,但是我们可以伸出手来,自己去拿。也就是所谓的数据

    抓取。

      这里介绍两个使用的工具,httpClient以及jsoup,简介如下:


      HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的项目中,比如Apache Jakarta上很著名的另外两个开源项目Cactus和HTMLUnit都使用了HttpClient。

    httpClient使用方法如下:

      1. 创建HttpClient对象。

      2. 创建请求方法的实例,并指定请求URL。

      3. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。

      4. 调用HttpResponse相关方法获取相应内容。

      5. 释放连接。

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

      需要更多信息可以参见官网下载地址 

      httpClient:http://hc.apache.org/httpcomponents-client-5.0.x/index.html

      jsoup:http://jsoup.org/

      

      接下来我们直接上代码,这里我们抓取2345在线万年历的数据 http://tools.2345.com/rili.htm

      首先我们定义一个实体类Almanac来存储黄历数据

    Almanac.java:

    package com.tydic.eshop.common;
     /**
      * 万年历工具实体类
      * 
      * @author 
      * 2016年4月11日
      */
    public class Almanac {
    
        private String solar; /* 阳历 e.g.2016年 4月11日 星期一 */
        private String lunar; /* 阴历 e.g. 猴年 三月初五 */
        private String chineseAra; /* 天干地支纪年法 e.g.丙申年 壬辰月 癸亥日 */
        private String should; /* 宜e.g. 求子 祈福 开光 祭祀 安床 */
        private String avoid; /* 忌 e.g. 玉堂(黄道)危日,忌出行 */
        
        public String getSolar() {
            return solar;
        }
        public void setSolar(String solar) {
            this.solar = solar;
        }
        public String getLunar() {
            return lunar;
        }
        public void setLunar(String lunar) {
            this.lunar = lunar;
        }
        public String getChineseAra() {
            return chineseAra;
        }
        public void setChineseAra(String chineseAra) {
            this.chineseAra = chineseAra;
        }
        public String getShould() {
            return should;
        }
        public void setShould(String should) {
            this.should = should;
        }
        public String getAvoid() {
            return avoid;
        }
        public void setAvoid(String avoid) {
            this.avoid = avoid;
        }
        
        
    }

     然后是抓取解析的主程序,写程序之前需要在官网下载需要的jar包

      AlmanacUtil.java

    package com.likx.picker.util;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.ParseException;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    /**
     *<STRONG>类描述</STRONG> :  2345万年历信息爬取工具<p>
     *   
     * @version 1.0 <p>
     * @author 
     * 
     * <STRONG>创建时间</STRONG> : 2016年4月11日 下午14:15:44<p>
     * <STRONG>修改历史</STRONG> :<p>
     *<pre>
     * 修改人                   修改时间                     修改内容
     * ---------------         -------------------         -----------------------------------
     *</pre>
     */
    public class AlmanacUtil {
        
        /**
         * 单例工具类
         */
        private AlmanacUtil() {
        }
        /**
         * 获取万年历信息
         * @return
         */
        public static Almanac getAlmanac(){
            String url="http://tools.2345.com/rili.htm";
            String html=pickData(url);
            Almanac almanac=analyzeHTMLByString(html);
            return almanac;
        }
        
        /*
         * 爬取网页信息
         */
        private static String pickData(String url) {
            CloseableHttpClient httpclient = HttpClients.createDefault();
            try {
                HttpGet httpget = new HttpGet(url);
                CloseableHttpResponse response = httpclient.execute(httpget);
                try {
                    // 获取响应实体
                    HttpEntity entity = response.getEntity();
                    // 打印响应状态
                    if (entity != null) {
                        return EntityUtils.toString(entity);
                    }
                } finally {
                    response.close();
                }
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (ParseException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 关闭连接,释放资源
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
        
        /*
         * 使用jsoup解析网页信息
         */
        private static Almanac analyzeHTMLByString(String html){
            String solarDate,lunarDate,chineseAra,should,avoid=" ";
            Document document = Jsoup.parse(html);
            //公历时间
            solarDate=getSolarDate();
            //农历时间
            Element eLunarDate=document.getElementById("info_nong");
            lunarDate=eLunarDate.child(0).html().substring(1,3)+eLunarDate.html().substring(11);
            //天干地支纪年法
            Element eChineseAra=document.getElementById("info_chang");
            chineseAra=eChineseAra.text().toString();    
            //
            should=getSuggestion(document,"yi");
            //
            avoid=getSuggestion(document,"ji");
            Almanac almanac=new Almanac(solarDate,lunarDate,chineseAra,should,avoid);
            return almanac;
        }
        /*
         * 获取忌/宜
         */
        private static String getSuggestion(Document doc,String id){
            Element element=doc.getElementById(id);
            Elements elements=element.getElementsByTag("a");
            StringBuffer sb=new StringBuffer();
            for (Element e : elements) {
                sb.append(e.text()+" ");
            }
            return sb.toString();
        }
    
        /*
         * 获取公历时间,用yyyy年MM月dd日 EEEE格式表示。
         * @return yyyy年MM月dd日 EEEE
         */
        private static String getSolarDate() {
            Calendar calendar = Calendar.getInstance();
            Date solarDate = calendar.getTime();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 EEEE");
            return formatter.format(solarDate);
        }
    
    }

     为了简单明了我把抓取解析抽象成了几个独立的方法,

      其中pickData()方法使用httpClient来抓取数据到一个字符串中(就是在网页上点击查看源代码看到的HTML源码),

    analyzeHTMLByString()方法来解析抓取到的字符串,getSuggestion方法把抓取方法类似的宜忌数据抽象到了

    一起,另外因为公历时间可以很容易的自己生成就没有在网页上爬取。

      然后下面是一个测试类简单测试下效果:

     AlmanacUtilTest.java

    package com.likx.picker.util.test;
    
    public class AlmanacUtilTest {
        
        public static void main(String args[]){
            Almanac almanac=AlmanacUtil.getAlmanac();
            System.out.println("公历时间:"+almanac.getSolar());
            System.out.println("农历时间:"+almanac.getLunar());
            System.out.println("天干地支:"+almanac.getChineseAra());
            System.out.println("宜:"+almanac.getShould());
            System.out.println("忌:"+almanac.getAvoid());
        }
    }

    运行结果如下:

  • 相关阅读:
    【HDU】4092 Nice boat(多校第四场1006) ——线段树 懒惰标记 Prime
    【POJ】2528 Mayor's posters ——离散化+线段树 Prime
    【HDU】1754 I hate it ——线段树 单点更新 区间最值 Prime
    C语言 linux环境基于socket的简易即时通信程序 Prime
    Java异常处理
    重载和重写的区别与联系
    SQL Server的优点与缺点
    Servlet基础
    C语言图形编程
    socket通讯,TCP,UDP,HTTP的区别
  • 原文地址:https://www.cnblogs.com/lr393993507/p/5405044.html
Copyright © 2020-2023  润新知