生活随笔
收集整理的這篇文章主要介紹了
微信公众帐号开发教程第16篇-应用实例之历史上的今天
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
內容概要
本篇文章主要講解如何在微信公眾帳號上實現“歷史上的今天”功能。這個例子本身并不復雜,但希望通過對它的學習,讀者能夠對正則表達式有一個新的認識,能夠學會運用現有的網絡資源豐富自己的公眾賬號。
何謂歷史上的今天
回顧歷史的長河,歷史是生活的一面鏡子;以史為鑒,可以知興衰;歷史上的每一天,都是喜憂參半;可以了解歷史的這一天發生的事件,借古可以鑒今,歷史是不能忘記的。查看歷史上每天發生的重大事情,增長知識,開拓眼界,提高人文素養。
尋找接口(數據源)
要實現查詢“歷史上的今天”,首先我們要找到相關數據源。筆者經過搜索發現,網絡上幾乎沒有現成的“歷史上的今天”API可以使用,所以我們只能通過爬取、解析網頁源代碼的方式得到我們需要的數據。筆者發現網站http://www.rijiben.com/上包含“歷史上的今天”功能,就用它做數據源了。
開發步驟
為了便于讀者理解,我們需要清楚該應用實例的開發步驟,主要如下:
1)發起HTTP GET請求,獲取網頁源代碼。
2)運用正則表達式從網頁源代碼中抽取我們需要的數據。
3)對抽取得到的數據進行加工(使內容呈現更加美觀)。
4)將以上三步進行封裝,供外部調用。
5)在公眾賬號后臺調用封裝好的“歷史上的今天”查詢方法。
代碼實現
筆者將上述步驟1)、2)、3)中的代碼實現封裝成了TodayInHistoryService類,并對外提供了getTodayInHistory()方法來獲取“歷史上的今天”。實現代碼如下:
import?java.io.BufferedReader;??import?java.io.InputStream;??import?java.io.InputStreamReader;??import?java.net.HttpURLConnection;??import?java.net.URL;??import?java.text.DateFormat;??import?java.text.SimpleDateFormat;??import?java.util.Calendar;??import?java.util.regex.Matcher;??import?java.util.regex.Pattern;????????????public?class?TodayInHistoryService?{???????????????????private?static?String?httpRequest(String?requestUrl)?{??????????StringBuffer?buffer?=?null;????????????try?{????????????????????????????URL?url?=?new?URL(requestUrl);??????????????HttpURLConnection?httpUrlConn?=?(HttpURLConnection)?url.openConnection();??????????????httpUrlConn.setDoInput(true);??????????????httpUrlConn.setRequestMethod("GET");??????????????????????????????InputStream?inputStream?=?httpUrlConn.getInputStream();??????????????InputStreamReader?inputStreamReader?=?new?InputStreamReader(inputStream,?"utf-8");??????????????BufferedReader?bufferedReader?=?new?BufferedReader(inputStreamReader);??????????????????????????????buffer?=?new?StringBuffer();??????????????String?str?=?null;??????????????while?((str?=?bufferedReader.readLine())?!=?null)?{??????????????????buffer.append(str);??????????????}??????????????????????????????bufferedReader.close();??????????????inputStreamReader.close();??????????????inputStream.close();??????????????httpUrlConn.disconnect();??????????}?catch?(Exception?e)?{??????????????e.printStackTrace();??????????}??????????return?buffer.toString();??????}???????????????????private?static?String?extract(String?html)?{??????????StringBuffer?buffer?=?null;????????????????????String?dateTag?=?getMonthDay(0);????????????Pattern?p?=?Pattern.compile("(.*)(<div?class=\"listren\">)(.*?)(</div>)(.*)");??????????Matcher?m?=?p.matcher(html);??????????if?(m.matches())?{??????????????buffer?=?new?StringBuffer();??????????????if?(m.group(3).contains(getMonthDay(-1)))??????????????????dateTag?=?getMonthDay(-1);??????????????????????????????buffer.append("≡≡?").append("歷史上的").append(dateTag).append("?≡≡").append("\n\n");??????????????????????????????for?(String?info?:?m.group(3).split("??"))?{??????????????????info?=?info.replace(dateTag,?"").replace("(圖)",?"").replaceAll("</?[^>]+>",?"").trim();????????????????????????????????????if?(!"".equals(info))?{??????????????????????buffer.append(info).append("\n\n");??????????????????}??????????????}??????????}????????????????????return?(null?==?buffer)???null?:?buffer.substring(0,?buffer.lastIndexOf("\n\n"));??????}??????????????????private?static?String?getMonthDay(int?diff)?{??????????DateFormat?df?=?new?SimpleDateFormat("M月d日");??????????Calendar?c?=?Calendar.getInstance();??????????c.add(Calendar.DAY_OF_YEAR,?diff);??????????return?df.format(c.getTime());??????}??????????????????public?static?String?getTodayInHistoryInfo()?{????????????????????String?html?=?httpRequest("http://www.rijiben.com/");????????????????????String?result?=?extract(html);????????????return?result;??????}??????????????????public?static?void?main(String[]?args)?{??????????String?info?=?getTodayInHistoryInfo();??????????System.out.println(info);??????}??}??
代碼解讀:
1)27-58行代碼是httpRequest()方法,用于發起http get請求,獲取指定url的網頁源代碼。
2)66-92行代碼是extract()方法,運用正則表達式從網頁源代碼中抽取“歷史上的今天”數據。
3)111-118行代碼是getTodayInHistory()方法,封裝給外部調用查詢“歷史上的今天”。
4)125-128行代碼是main方法,用于在本地的開發工具中測試。
5)75-76行代碼的作用是判斷獲取到的“歷史上的今天”數據是當天的還是前一天的(因為不能保證www.rijiben.com上的數據一定在凌晨零點準時更新,所以為了保證數據的準確性必須做此判斷)。
6)第71行代碼是本文的重點,筆者編寫的正則表達式規則是“(.*)(<div class=\"listren\">)(.*?)(</div>)(.*)”。正則表達式規則需要根據網頁源代碼進行編寫的,特別是包含“歷史上的今天”數據的那部分HTML標簽,所以我們先來查看網頁源代碼。通過httpRequest("http://www.rijiben.com/")方法獲取到的網頁源代碼,與我們通過瀏覽器訪問http://www.rijiben.com/頁面再點擊右鍵選擇“查看網頁源代碼”所得到的結果完全一致。我們通過瀏覽器查看http://www.rijiben.com/的網頁源代碼,然后找到“歷史上的今天”數據所在位置,如下圖所示:
從上面的源代碼截圖中可以看到,我們需要的數據被包含在<div class="listren">標簽內,這樣就不難理解為什么正則表達式要這樣寫:
(.*)(<div class=\"listren\">)(.*?)(</div>)(.*)
我們使用括號()將正則表達式規則分成了5組,下面是這些分組的說明:
第1組:(.*)表示網頁源代碼中<div class="listren">標簽之前還有任意多個字符。
第2組:(<div class=\"listren\">)中的反斜杠表示轉義,所以該規則就是用于匹配<div class="listren">。
第3組:(.*?)表示在標簽<div class="listren">和</div>之間的所有內容,這才是我們真正需要的數據所在。
第4組:(</div>)就是用于匹配<div class="listren">的結束標簽。
第5組:(.*)表示在</div>標簽之后還有任意多的字符。
掌握了正則表達式規則的含義,就不難理解為什么在extract()方法中全都是在使用m.group(3),因為m.group(3)就表示匹配到數據的第3個分組。m.group(3)的內容如下:
<ul>??????????????????????<li><a?href="/news6836/"?title="0690年10月16日?武則天登上皇位">0690年10月16日?武則天登上皇位</a>??(圖)</li>??????????????????????<li><a?href="/news6837/"?title="1854年10月16日?唯美主義運動的倡導者王爾德誕辰">1854年10月16日?唯美主義運動的倡導者王爾德誕辰</a>??</li>??????????????????????<li><a?href="/news6838/"?title="1854年10月16日?德國社會主義活動家考茨基誕生">1854年10月16日?德國社會主義活動家考茨基誕生</a>??</li>??????????????????????<li><a?href="/news6839/"?title="1908年10月16日?阿爾巴尼亞領導人恩維爾·霍查誕辰">1908年10月16日?阿爾巴尼亞領導人恩維爾·霍查誕辰</a>??(圖)</li>??????????????????????<li><a?href="/news6840/"?title="1913年10月16日?中國“兩彈一星”元勛錢三強誕辰">1913年10月16日?中國“兩彈一星”元勛錢三強誕辰</a>??(圖)</li>??????????????????????<li><a?href="/news6841/"?title="1922年10月16日?開灤煤礦工人罷工失敗">1922年10月16日?開灤煤礦工人罷工失敗</a>??(圖)</li>??????????????????????<li><a?href="/news6842/"?title="1927年10月16日?德國諾貝爾文學獎得主格拉斯誕生">1927年10月16日?德國諾貝爾文學獎得主格拉斯誕生</a>??(圖)</li>??????????????????????<li><a?href="/news6843/"?title="1933年10月16日?抗日同盟軍失敗">1933年10月16日?抗日同盟軍失敗</a>??(圖)</li>??????????????????????<li><a?href="/news6844/"?title="1950年10月16日?人民解放軍進軍西藏">1950年10月16日?人民解放軍進軍西藏</a>??(圖)</li>??????????????????????<li><a?href="/news6845/"?title="1954年10月16日?俞平伯《關于紅樓夢研究問題的信》發表">1954年10月16日?俞平伯《關于紅樓夢研究問題的信》發表</a>??(圖)</li>??????????????????????<li><a?href="/news6846/"?title="1959年10月16日?美軍將領、國務卿馬歇爾去世">1959年10月16日?美軍將領、國務卿馬歇爾去世</a>??(圖)</li>??????????????????????<li><a?href="/news6847/"?title="1964年10月16日?勃列日涅夫取代赫魯曉夫??成為蘇共中央第一書記">1964年10月16日?勃列日涅夫取代赫魯曉夫??成為蘇共中央第一書記</a>??</li>??????????????????????<li><a?href="/news6848/"?title="1964年10月16日?我國第一顆原子彈爆炸成功">1964年10月16日?我國第一顆原子彈爆炸成功</a>??(圖)</li>??????????????????????<li><a?href="/news6849/"?title="1973年10月16日?震撼世界的石油危機爆發">1973年10月16日?震撼世界的石油危機爆發</a>??(圖)</li>??????????????????????<li><a?href="/news6850/"?title="1978年10月16日?約翰·保羅二世當選新教皇">1978年10月16日?約翰·保羅二世當選新教皇</a>??</li>??????????????????????<li><a?href="/news6851/"?title="1979年10月16日?哈克將軍宣布巴基斯坦推遲大選解散政黨">1979年10月16日?哈克將軍宣布巴基斯坦推遲大選解散政黨</a>??</li>??????????????????????<li><a?href="/news6852/"?title="1984年10月16日?圖圖主教榮獲“諾貝爾和平獎”">1984年10月16日?圖圖主教榮獲“諾貝爾和平獎”</a>??</li>??????????????????????<li><a?href="/news6853/"?title="1988年10月16日?北京正負電子對撞機對撞成功">1988年10月16日?北京正負電子對撞機對撞成功</a>??(圖)</li>??????????????????????<li><a?href="/news6854/"?title="1991年10月16日?美國小鎮槍殺案22人喪生">1991年10月16日?美國小鎮槍殺案22人喪生</a>??</li>??????????????????????<li><a?href="/news6855/"?title="1991年10月16日?莫扎特死因有新說">1991年10月16日?莫扎特死因有新說</a>??</li>??????????????????????<li><a?href="/news6856/"?title="1991年10月16日?錢學森獲“國家杰出貢獻科學家”殊榮">1991年10月16日?錢學森獲“國家杰出貢獻科學家”殊榮</a>??(圖)</li>??????????????????????<li><a?href="/news6857/"?title="1994年10月16日?德國總理科爾四連任">1994年10月16日?德國總理科爾四連任</a>??</li>??????????????????????<li><a?href="/news6858/"?title="1994年10月16日?第十二屆廣島亞運會閉幕">1994年10月16日?第十二屆廣島亞運會閉幕</a>??</li>??????????????????????<li><a?href="/news6859/"?title="1994年10月16日?修秦陵制秦俑工匠墓葬被發現">1994年10月16日?修秦陵制秦俑工匠墓葬被發現</a>??</li>??????????????????????<li><a?href="/news6860/"?title="1995年10月16日?美國百萬黑人男子大游行">1995年10月16日?美國百萬黑人男子大游行</a>??(圖)</li>????????????????????</ul>?????????
可以看到,
通過正則表達式抽取得到的m.group(3)中仍然有大量的html標簽、空格、換行、無關字符等。
我們要想辦法把它們全部過濾掉,第83行代碼的作用正是如此。
組裝文本消息
??TextMessage?textMessage?=?new?TextMessage();??textMessage.setToUserName(fromUserName);??textMessage.setFromUserName(toUserName);??textMessage.setCreateTime(new?Date().getTime());??textMessage.setMsgType(WeixinUtil.RESP_MESSAGE_TYPE_TEXT);??textMessage.setFuncFlag(0);??textMessage.setContent(TodayInHistoryService.getTodayInHistoryInfo());??
對于公眾帳號的消息回復在本系列教程的第5篇已經講的很詳細了,所以在這里筆者只是簡單的組裝了文本消息。最后,我們來看一下在微信公眾帳號上的演示效果:
總結
以上是生活随笔為你收集整理的微信公众帐号开发教程第16篇-应用实例之历史上的今天的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。