利用Fiddler手機抓包對ONE·APP網頁爬蟲實現電影資訊微信Java開發
前言
好久沒寫部落格了,打算把之前做的一個電影評分資訊推送的微信開發全程記錄一下,適合對網路爬蟲、微信開發感興趣的童鞋。在教程開始之前,我想先引出兩個問題(這次寫部落格假裝很有條理的樣子= =)
1. 為什麼想要抓取ONE電影的資料?
因為我平時本身就喜歡去電影院看電影,所以關注到ONE·APP有電影欄目,而且評分資訊一目瞭然,非常適合我這種人,該看哪一部你懂的~(PS:這是寫部落格當天截的圖,下週末去看82分機器貓,嘿嘿)
當然了,豆瓣電影也有評分,但是感覺那裡水軍很多,所以資料參考價值不大吧。順便普及一下,“一個”APP是由韓寒創立的,最初只有文學欄目,2016年初才進軍電影行業(
2. 我需要提前準備什麼東西?
- 首先,你得有一臺手機(你是不是傻?請忽略這條),如果16g蘋果沒記憶體可用安卓模擬器代替。。。(沒有別的意思…)
- 其次,你得有java網路爬蟲相關知識,主要是httpclient的使用,解析JSON用的是效率較高的jackson。
- 最後,你得有微信java開發經驗,主要解決資料呈現問題,當然你也可以使用僅用的JAVA EE知識做一個網頁來呈現資料。因為不能面面俱到,所以此教程可能不會過多講解這一塊內容,這裡推薦慕課網視訊教程,建議直奔重點看第五章,十分受用。
對了,先放個圖,看下微信開發的功能最終效果,噔噔噔噔~↓
還是像模像樣的,前面bb了那麼多,下面開始我們的教程吧!
思路
1. 抓取資料(Fidder抓包,手機wifi代理)
2. 分析資料(解析JSON/HTML,提取有用資訊)
3. 微信開發(文字訊息匹配、被動回覆圖文)
基本思路是對資料的抓取→分析→處理→呈現,下面以ONE·APP的電影資料為例,本教程會把重點放在前面兩part。
實戰
1. 抓取資料
前期準備
下載抓包工具Fiddler:大家到網上去下載就好了,我這裡用的是
V4.6
。設定Fiddler規則(關鍵):點
Tools->Fiddler Options->HTTPS
Capture HTTPS CONNECTs
和Decrypt HTTPS traffic
這兩項,建議勾上ignore server certificate erros (unsafe)
保證我們抓包時候不會狂彈窗而影響心情;切換到Connections
選項卡,再勾選allow remote computers to connect
這項,記住這裡出現的Fiddler listens on port
埠號是8888(當然這裡可以自己改成別的,但是建議不要這樣做),之後會用到它。
設定完必須重啟Fiddler搭建網路環境:使電腦和手機在同一個區域網下,這個為之後的手機wifi代理做準備。
檢視電腦內網IP:在命令列輸入
ipconfig
檢視內網IP,我這裡查到是192.168.2.106,先記住,下面會用到。
設定手機wifi代理(關鍵):不用手機可能有點不一樣,我這裡以我的安卓小錘子來做示範。
設定->無線網路->已連線的網路詳細->高階設定
,開啟手動HTTP代理
,填寫代理伺服器主機名
為電腦內網IP 192.168.2.106,以及代理伺服器埠
為Fiddler顯示的8888。其他系統和型號的手機自己琢磨下吧~
手機下載“一個”APP:在各大手機應用市場搜尋
一個
、ONE
、韓寒
均可下載。
下面開始才是重點
手機開啟“一個”APP,在抓包之前先清理Fiddler剛剛的抓取到的包,方便我們等下篩選。
點開“電影”欄目,觀察Fiddler的抓包情況。到這裡你已經成功了一半了,host為
wufazhuce.com
正是“一個”的域名,而且url為/api/movie/list/0?
(這很restful…),可以確定是我們想要的那個請求。
(但是在實際抓包中,往往會有各種各樣的無用資訊摻雜在裡面,這時候就需要我們去辨別哪些是我們想要的url)
我們通過直接訪問剛剛抓取到的url:http://v3.wufazhuce.com:8000/api/movie/list/0?
,打開發現返回的是json格式的資料,正是我們想要的。到此為止,我們的抓取資料part已經完成了,應該不困難吧= =
沒有抓取到包可能出現的原因:
- 電腦和手機不在同一個區域網內
- Fiddler設定不對
- 手機wifi沒有代理成功,可能是填寫有誤,也可能是手機系統問題
- 最有可能的是我之前遇到的問題:設定完代理後,要先關閉APP,再重新開啟
- 人品問題,自行百度,也歡迎留言哈~
更多API分享
電影詳情:
http://v3.wufazhuce.com:8000/api/movie/detail/ID
首頁電影故事:
http://v3.wufazhuce.com:8000/api/movie/ID/story/1/0
全部電影故事:
http://v3.wufazhuce.com:8000/api/movie/ID/story/0/0
熱門評論(點贊數)
http://v3.wufazhuce.com:8000/api/comment/praise/movie/ID/0
全部評論(發表時間)
http://v3.wufazhuce.com:8000/api/comment/time/movie/ID/0
注意:所有URL中的ID
替換為實際的電影ID
即可,最後以為引數0所代表的含義代表下標ID,在下文中會提及到,預設寫0。
2.分析資料
我們選擇那條請求,檢視軟體右邊的請求詳細分析,由於我們事先知道請求返回資料型別是json,所以我們點
Inspectors
選項卡下的JSON
選項卡,如下圖。
我們把有用的資訊記錄下來,很有必要。
請求方式&地址:GET http://v3.wufazhuce.com:8000/api/movie/list/0
備註:url中的最後一個引數代表電影ID下標,用於分頁功能,假如你第一頁最後一個電影記錄的ID是84,那麼你再次請求地址http://v3.wufazhuce.com:8000/api/movie/list/84,得到的資料就是從85開始,也就是下一頁電影的資料。這裡要靠大家軟體開發的經驗以及親手嘗試過才知道,聽不懂也沒關係,這一個引數不足以影響我們的開發。你只要知道預設是0,獲取最新的電影資料就行了。
json返回部分有用資料{ "res": 0, "data": [ { "id": "103", "title": "哆啦A夢:新·大雄的日本誕生", "score": "82", "cover": "http://image.wufazhuce.com/FsaiDxnewphDWZvTn021Si22ZaMv" } ] }
引數 型別 說明 res int 返回碼:0-成功,1-失敗 data array 資料集合 - id
int 電影ID,唯一標識 - title
string 電影名 - score
int 評分 - cover
string 封面地址
當然了,這種是json資料格式的分析過程,這個跟過程跟你得業務有關,而我只需要實現一開始所呈現的那種圖片效果,以上這些資料就夠了。使用jackson來解析資料。
如果返回的資料是xml格式,也很好辦,跟json差不多,使用xstream解析。
如果返回的資料是帶檢視模型(也就是有頁面的),那就要用瀏覽器審查元素或者檢視原始碼,細心觀察需要爬取的資料都在哪些div裡面,觀察它或者它的父元素是否有什麼標誌性的id甚至是class,這樣就能通過jsoup解析它們。網頁爬蟲可以參考我上一篇爬蟲文章《基於WebMagic寫的一個csdn部落格小爬蟲》,框架裡面用到的就是強大的jsoup。
資料分析完後,接下來就是真正的coding了!
3.微信開發
新增maven依賴(maven配置視訊,或者手動下載jar包)
<!-- HttpClient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.3.6</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.3.6</version> </dependency> <!-- JSON --> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency> <!-- XML --> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.7</version> </dependency> <!-- HTML --> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.9.2</version> </dependency> <!-- IO --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
新增wx-tools.jar(我一個室友寫的框架,下載jar包,檢視官方文件,3分鐘上手教程)
當然了,如果嫌麻煩你可以不使用任何的微信後臺框架,如果沒學習過微信java開發的請移步到慕課網視訊教程,直奔重點看第五章。編寫爬蟲業務(重點)
package com.soecode.xfshxzs.service; /** * 電影爬蟲業務 */ public class MovieService { // 電影列表URL private static final String MOVIE_LIST_URL = "http://v3.wufazhuce.com:8000/api/movie/list/0"; /** * 獲取電影列表 * * @return */ public List<Movie> getMovieList() { List<Movie> list = new ArrayList<Movie>(); try { String json = HttpUitl.doGet(MOVIE_LIST_URL); ObjectMapper mapper = new ObjectMapper(); JsonNode root = mapper.readTree(json); JsonNode data = root.path("data"); if (data.isArray()) { for (JsonNode node : data) { Movie movie = mapper.readValue(node, Movie.class); list.add(movie); } } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return list; } }
自己寫的一個HTTP工具類,擁有doGet方法,實現了傳入一個url,輸出網頁字串文字。
package com.soecode.xfshxzs.util; /** * HTTP工具類 */ public class HttpUitl { /** * 普通GET請求 * * @param uri * @return * @throws IOException * @throws ClientProtocolException */ public static String doGet(String uri) throws ClientProtocolException, IOException { String html = null; CloseableHttpClient httpClient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(uri); CloseableHttpResponse response = httpClient.execute(httpGet); HttpEntity entity = response.getEntity(); if (entity != null) { html = EntityUtils.toString(entity); EntityUtils.consume(entity); } httpGet.releaseConnection(); response.close(); return html; } }
編寫處理器:呼叫業務方法,實現星星效果,裝配圖文訊息,傳送給使用者
package com.soecode.xfshxzs.handler; /** * 電影訊息處理器 */ public class MovieMessageHandler implements WxMessageHandler { private MovieService movieService = new MovieService(); public WxXmlOutMessage handle(WxXmlMessage wxMessage, Map<String, Object> context, WxService wxService) throws WxErrorException { String content = wxMessage.getContent(); List<Movie> list = movieService.getMovieList(); for (int i = 0; i < 8; i++) { Item item = new Item(); item.setTitle(movieDetail.getScore() + "分 " + createStarsByScore(movieDetail.getScore()) + " | " + movieDetail.getTitle()); item.setPicUrl(movieDetail.getDetailcover()); builder.addArticle(item); } return WxXmlOutMessage.NEWS().toUser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName()).build(); } /** * 根據分數建立星星 * * @param score * @return */ private String createStarsByScore(int score) { String stars = ""; int solidStarsNum = Math.floorDiv(score + 10, 20); for (int i = 0; i < solidStarsNum; i++) { stars += "★"; } int hollowStarsNum = 5 - solidStarsNum; for (int i = 0; i < hollowStarsNum; i++) { stars += "☆"; } return stars; } }
新建攔截規則:匹配文字類訊息“電影”,看不懂也沒關係,真的沒關係= =
router.rule().async(false).msgType(WxConsts.XML_MSG_TEXT).rContent("電影").handler(new MovieMessageHandler()).end();
- 剩下就是微信伺服器驗證了,在開發過程中我們應該本地除錯過才放到自己伺服器上,之前使用的內網對映(穿透)工具ngrok(懷念一下)不知道何時用不了了,所以一直在用很不穩定的花生殼,大家自己選擇吧。到此為止,我們的教程已經順利完成了,此處應有掌聲,啪啪啪啪~
要原始碼請繼續往下看↓
後記
教程中只涉及到了電影資訊的爬蟲,還有查天氣、查快遞等更多功能請關注公眾號盡情調戲(好像有BUG?),僅作為一個DEMO參考。放二維碼目的不是為了增粉啊,真的不是啊,只是想演示以上教程,趕緊掃吧~
很感謝大家能夠看到這裡,你們的每一個閱讀量都是對我莫大的鼓勵!(如果能去github給個贊就更好啦~嘻嘻~)
哦對了,說到電影,我要順便給你們一點福(an)利,以下是我的電影日常= =。
男神福利:如何低價購買電影票?(知乎網友攻略)
宅男福利:高清控聯盟(專注高清藍光)
凌晨了,要睡覺了,又寫到這麼晚= = 以後不能再這樣了!!
在接下來的大學裡最後一個暑假,我要好好看完剛從圖書館裡借來的兩本書,加油!fighting!!