標籤:多次 alt str pat 貴的 amr 網頁資料 請求 換行
原文地址https://www.cnblogs.com/xiaoMzjm/p/3894805.html
【本文介紹】
爬取別人網頁上的內容,聽上似乎很有趣的樣子,只要幾步,就可以擷取到力所不能及的東西,例如呢?例如天氣預報,總不能自己拿著儀器去測吧!當然,要擷取天氣預報還是用webService好。這裡只是舉個例子。話不多說了,上看看效果吧。
【效果】
我們隨便找個天氣預報的網站來試試:http://www.weather.com.cn/html/weather/101280101.shtml
可用看出,今天(6日)的天氣。我們就以這個為例,擷取今天的天氣吧!
最終後台列印出:
今天:6日天氣:雷陣雨溫度:26°~34°風力:微風
【思路】
1、通過url擷取輸入資料流————2、擷取網頁html代碼————3、用Regex抽取有用的資訊————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>)(.*) 這個Regex,很容易看出可以分為下面5組:
(.*) :匹配除分行符號外任意東西0-N次
(<li class=\‘dn on\‘ data-dn=\‘7d1\‘>) :匹配中間那段heml代碼一次
(.*?) : .*?為匹配的懶惰模式,意思是匹配除分行符號外任意東西儘可能少次
(</li>) :匹配中間那段html代碼一次
(.*) :匹配除分行符號外任意東西0-N次
這樣,我們就可用m.group(3)拿到匹配中間(.*?)的那一串代碼了。即我們需要的“今天”的天氣的代碼。
101行:中間那一段代碼拿出來後如所示、還有很多無用的標籤。我們要想辦法繼續除去。方法同上。
106行:手動拼接上我們需要的字串。
經過以上的處理,就完成了一個簡單的爬取啦。
中間Regex部分最不滿意,各路網友如果有好的建議麻煩留下寶貴的評論,感激不盡~
java通過url抓取網頁資料-----Regex