首页 > 代码库 > java网页爬虫简单实例详解——获取天气预报。

java网页爬虫简单实例详解——获取天气预报。

  【本文介绍】  

爬取别人网页上的内容,听上似乎很有趣的样子,只要几步,就可以获取到力所不能及的东西,例如呢?例如天气预报,总不能自己拿着仪器去测吧!当然,要获取天气预报还是用webService好。这里只是举个例子。话不多说了,上看看效果吧。

  【效果】

我们随便找个天气预报的网站来试试:http://www.weather.com.cn/html/weather/101280101.shtml

从图中可用看出,今天(6日)的天气。我们就以这个为例,获取今天的天气吧!

最终后台打印出:

今天:6日天气:雷阵雨温度:26°~34°风力:微风

 

    【思路】

1、通过url获取输入流————2、获取网页html代码————3、用正则表达式抽取有用的信息————4、拼装成想要的格式

 其实最难的一点事第3点,如果正则表示式不熟,基本上在这一步就会挂掉了——例如我T_T。下面为了抽取到正确的数据,我匹配了多次,如果能一次匹配的话,那代码量就少多了!

  【代码】

  1 package com.zjm.www.test;  2   3 import java.io.BufferedReader;  4 import java.io.IOException;  5 import java.io.InputStream;  6 import java.io.InputStreamReader;  7 import java.net.HttpURLConnection;  8 import java.net.URL;  9 import java.util.regex.Matcher; 10 import java.util.regex.Pattern; 11  12 /** 13  * 描述:趴取网页上的今天的天气 14  * @author     zjm     15  * @time     2014/8/6 16  */ 17 public class TodayTemperatureService { 18      19      /**  20      * 发起http get请求获取网页源代码  21      * @param requestUrl     String    请求地址 22      * @return                 String    该地址返回的html字符串 23      */   24     private static String httpRequest(String requestUrl) {   25          26         StringBuffer buffer = null;   27         BufferedReader bufferedReader = null; 28         InputStreamReader inputStreamReader = null; 29         InputStream inputStream = null; 30         HttpURLConnection httpUrlConn = null; 31    32         try {   33             // 建立get请求 34             URL url = new URL(requestUrl);   35             httpUrlConn = (HttpURLConnection) url.openConnection();   36             httpUrlConn.setDoInput(true);   37             httpUrlConn.setRequestMethod("GET");   38    39             // 获取输入流   40             inputStream = httpUrlConn.getInputStream();   41             inputStreamReader = new InputStreamReader(inputStream, "utf-8");   42             bufferedReader = new BufferedReader(inputStreamReader);   43    44             // 从输入流读取结果 45             buffer = new StringBuffer();   46             String str = null;   47             while ((str = bufferedReader.readLine()) != null) {   48                 buffer.append(str);   49             }   50    51         } catch (Exception e) {   52             e.printStackTrace();   53         }  finally { 54             // 释放资源 55             if(bufferedReader != null) { 56                 try { 57                     bufferedReader.close(); 58                 } catch (IOException e) { 59                     e.printStackTrace(); 60                 } 61             } 62             if(inputStreamReader != null){ 63                 try { 64                     inputStreamReader.close(); 65                 } catch (IOException e) { 66                     e.printStackTrace(); 67                 } 68             } 69             if(inputStream != null){ 70                 try { 71                     inputStream.close(); 72                 } catch (IOException e) { 73                     e.printStackTrace(); 74                 } 75             } 76             if(httpUrlConn != null){ 77                 httpUrlConn.disconnect();   78             } 79         } 80         return buffer.toString();   81     }   82    83     /**  84      * 过滤掉html字符串中无用的信息 85      * @param html    String    html字符串 86      * @return         String    有用的数据 87      */  88     private static String htmlFiter(String html) {   89          90         StringBuffer buffer = new StringBuffer();   91         String str1 = ""; 92         String str2 = ""; 93         buffer.append("今天:"); 94          95         // 取出有用的范围 96         Pattern p = Pattern.compile("(.*)(<li class=\‘dn on\‘ data-dn=\‘7d1\‘>)(.*?)(</li>)(.*)");   97         Matcher m = p.matcher(html);   98         if (m.matches()) {   99             str1 = m.group(3);100             // 匹配日期,注:日期被包含在<h2> 和 </h2>中101             p = Pattern.compile("(.*)(<h2>)(.*?)(</h2>)(.*)");102             m = p.matcher(str1);103             if(m.matches()){104                 str2 = m.group(3);105                 buffer.append(str2);106                 buffer.append("\n天气:");107             }108             // 匹配天气,注:天气被包含在<p class="wea" title="..."> 和 </p>中109             p = Pattern.compile("(.*)(<p class=\"wea\" title=)(.*?)(>)(.*?)(</p>)(.*)");110             m = p.matcher(str1);111             if(m.matches()){112                 str2 = m.group(5);113                 buffer.append(str2);114                 buffer.append("\n温度:");115             }116             // 匹配温度,注:温度被包含在<p class=\"tem tem2\"> <span> 和 </span><i>中117             p = Pattern.compile("(.*)(<p class=\"tem tem2\"> <span>)(.*?)(</span><i>)(.*)");118             m = p.matcher(str1);119             if(m.matches()){120                 str2 = m.group(3);121                 buffer.append(str2);122                 buffer.append("°~");123             }124             p = Pattern.compile("(.*)(<p class=\"tem tem1\"> <span>)(.*?)(</span><i>)(.*)");125             m = p.matcher(str1);126             if(m.matches()){127                 str2 = m.group(3);128                 buffer.append(str2);129                 buffer.append("°\n风力:");130             }131             // 匹配风,注:<i> 和 </i> 中132             p = Pattern.compile("(.*)(<i>)(.*?)(</i>)(.*)");133             m = p.matcher(str1);134             if(m.matches()){135                 str2 = m.group(3);136                 buffer.append(str2);137             }138         }  139         return buffer.toString();140     }141     142     /** 143      *  对以上两个方法进行封装。144      * @return 145      */  146     public static String getTodayTemperatureInfo() {  147         // 调用第一个方法,获取html字符串148         String html = httpRequest("http://www.weather.com.cn/html/weather/101280101.shtml");  149         // 调用第二个方法,过滤掉无用的信息150         String result = htmlFiter(html);  151         152         return result;  153     }  154   155     /**156      * 测试157      * @param args158      */159     public static void main(String[] args) {  160         String info = getTodayTemperatureInfo();161         System.out.println(info);162     }  163 }

 

 【详解】

34-49行:通过url获取网页的源码,没什么好说的。

96行:在网页上按F12,查看"今天"的html代码,发现如下图,所以我们第一步就是要过滤掉除这一段html代码外的东西。

  (.*)(<li class=\‘dn on\‘ data-dn=\‘7d1\‘>)(.*?)(</li>)(.*) 这个正则表达式,很容易看出可以分为下面5组:

  (.*)                           :匹配除换行符外任意东西0-N次

  (<li class=\‘dn on\‘ data-dn=\‘7d1\‘>)    :匹配中间那段heml代码一次

  (.*?)                         : .*?为匹配的懒惰模式,意思是匹配除换行符外任意东西尽可能少次

  (</li>)                       :匹配中间那段html代码一次

  (.*)                       :匹配除换行符外任意东西0-N次

  这样,我们就可用m.group(3)拿到匹配中间(.*?)的那一串代码了。即我们需要的“今天”的天气的代码。

 

 

 101行:中间那一段代码拿出来后如下图所示、还有很多无用的标签。我们要想办法继续除去。方法同上。

106行:手动拼接上我们需要的字符串。

 

 经过以上的处理,就完成了一个简单的爬取啦。

 中间正则表达式部分最不满意,各路网友如果有好的建议麻烦留下宝贵的评论,感激不尽~