HttpClient + Jsoup模擬登陸教務處並獲取課表

  

一、概述

  最近想作一個校園助手類的APP,因爲第一次作,因此打算先把每一個功能單獨實現,防止亂了陣腳。利用教務處登陸獲取課表和成績等是一個基本功能,因此以獲取課表爲例實現了這個功能。完整代碼點這裏,嘗試了好幾回的,因此寫的比較亂html

二、涉及的關鍵知識

  首先,明確獲取課表的流程:其實,獲取課表就是讓手機模擬瀏覽器,給服務器傳去帳號、密碼,而後服務器會返回cookies(不懂自行百度),利用cookie就能夠穿梭自如了,好比查課表。可是,瀏覽器登陸時,返回的html文件瀏覽器是會自動解析成網頁展示在咱們面前的,可是APP就不行了,因此須要咱們本身從html字符流中解析出咱們須要的信息。就我本身的狀況來看,模擬登陸花了很多時間(這方面很不熟),解析html很快就解決了(多是以前實踐偶解析JSON)。java

  這樣一個APP主要涉及到3個重要知識點:node

一、如何模擬登陸:java有本身的HttpURLConnection,可是不夠靈活,因此用 apache的HttpClient更方便android

二、如何解析HTML:網上查一下,Jsoup很合適。web

三、AsyncTask:顯然獲取網頁並解析是不能再主線程進行的,因此須要使用異步任務。apache

四、回調函數:這個不是必須的,可是我爲了下降程序耦合度把網絡請求那部分單獨成了一個類,這時候更新主UI就須要利用回調函數了,以後細說設計模式

三、模擬登錄(以窩工UPR爲例)

  一、解析教務處登陸界面,看到一些教程用的仍是HttpWatch,確實過期了,顯然直接Google瀏覽器F12就好了。以下圖,選擇Network瀏覽器

  點一下登陸,就能夠看到一大堆信息,咱們須要的是第一個:服務器

 

  點擊就能夠看到詳細信息了:cookie

  重要的有兩個,Cookie,拿到這個咱們才能導出去訪問,Form Data就是模擬登陸時要提交(POST)的表單數據;

四、HTML解析

利用上一步模擬登陸拿到的Cookie就能夠去獲取課表了,同理,須要解析網頁,以下,點擊個人課表

 

  能夠看到一大堆信息,找到須要的

  這個Response就是會返回咱們的字符流,咱們須要的就是解析它,設計到Jsoup的詳細使用就不細說了,本身也是今天才接觸,

  總之藉助以上兩步就能夠寫出主要類Login.java的代碼了,以下:

  1 package com.example.upr.net;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.IOException;
  5 import java.io.InputStream;
  6 import java.io.InputStreamReader;
  7 import java.io.UnsupportedEncodingException;
  8 import java.util.ArrayList;
  9 import java.util.List;
 10 
 11 import org.apache.http.HttpEntity;
 12 import org.apache.http.HttpResponse;
 13 import org.apache.http.NameValuePair;
 14 import org.apache.http.client.ClientProtocolException;
 15 import org.apache.http.client.HttpClient;
 16 import org.apache.http.client.entity.UrlEncodedFormEntity;
 17 import org.apache.http.client.methods.HttpGet;
 18 import org.apache.http.client.methods.HttpPost;
 19 import org.apache.http.cookie.Cookie;
 20 import org.apache.http.impl.client.AbstractHttpClient;
 21 import org.apache.http.impl.client.DefaultHttpClient;
 22 import org.apache.http.message.BasicNameValuePair;
 23 import org.jsoup.Jsoup;
 24 import org.jsoup.nodes.Document;
 25 import org.jsoup.nodes.Element;
 26 import org.jsoup.select.Elements;
 27 
 28 import com.example.upr.CompleteListener;
 29 
 30 import android.R.integer;
 31 import android.os.AsyncTask;
 32 import android.provider.ContactsContract.Contacts.Data;
 33 import android.util.Log;
 34 import android.widget.Toast;
 35 
 36 public class Login extends AsyncTask<Void, Void, String[][]>{
 37 
 38     private String zjh;
 39     private String mm;
 40     private String webPage;
 41     private String [][] kebiao = new String[15][8];
 42     private CompleteListener listener;
 43     public Login(String account, String password, CompleteListener listener) {
 44         zjh = account;
 45         mm = password;
 46 
 47         this.listener = listener;
 48     }
 49     @Override
 50     protected String[][] doInBackground(Void... arg0) {
 51         List<NameValuePair> list = new ArrayList<NameValuePair>();
 52         list.add(new BasicNameValuePair("zjh", zjh));
 53         list.add(new BasicNameValuePair("mm", mm));//表單信息
 54         String encode = "gb2312";//編碼格式,從F12工具中能夠找到
 55         HttpClient httpClient = new DefaultHttpClient();
 56         List<Cookie> cookies;
 57         try {
 58             HttpEntity entity = new UrlEncodedFormEntity(list ,encode);//封裝數據
 59             HttpPost post = new HttpPost(com.example.upr.Constant.LOGIN_URL);//創建POST請求
 60             post.setEntity(entity);
 61             HttpResponse httpResponse = httpClient.execute(post);
 62             String data, result;
 63             if (httpResponse.getStatusLine().getStatusCode() == 200) {//登陸成功
 64                 cookies = ((AbstractHttpClient) httpClient).getCookieStore().getCookies();//獲取Cookie
 65                 HttpGet httpGet = new HttpGet("http://zhjw.dlut.edu.cn/xkAction.do?actionType=6");
 66                 httpGet.setHeader("Cookie", "JSESSIONID="+ cookies.get(0).getValue()+";"+
 67                         "NSC_kjbpxv-iuuq="+cookies.get(1).getValue());//注意分號
 68                 httpResponse = new DefaultHttpClient().execute(httpGet);
 69                 
 70                 StringBuffer sb = new StringBuffer();
 71                 entity = httpResponse.getEntity();
 72                 InputStream inputStream = entity.getContent();
 73                 BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, encode));
 74                 while ((data = br.readLine()) != null) {  
 75                     sb.append(data);  //讀取返回的網頁
 76                 }  
 77                 result = sb.toString();
 78                 webPage = result;
 79         
 80             } else {
 81                 return null;
 82             }
 83         } catch (UnsupportedEncodingException e) {
 84             e.printStackTrace();
 85             return null;
 86         } catch (ClientProtocolException e) {
 87             // TODO Auto-generated catch block
 88             e.printStackTrace();
 89             return null;
 90         } catch (IOException e) {
 91             // TODO Auto-generated catch block
 92             e.printStackTrace();
 93             return null;
 94         }
 95         
 96         Document document = Jsoup.parse(webPage);
 97         if (document != null) {
 98             Element element = document.getElementById("user");//經過id直接定位到數據
 99             Elements trElements = element.select("tr");
100             //如下是提取課表信息,每一個網站不一樣,一下代碼要解析的html放在最下面了
101             for (int i = 0; i < trElements.size(); i++) {
102                 Elements tdElements = trElements.get(i).select("td");
103                 for (int j = 0; j < tdElements.size(); j++) {
104                     String text = tdElements.get(j).text();
105                     if (tdElements.size() == 1) {
106                         continue;
107                     } else if (tdElements.size()==9) {
108                         if (j != 0) {
109                             kebiao[i][j-1] = text;
110                         }
111                     }else {
112                         kebiao[i][j] = text;
113                     }
114                     
115                 }
116             }
117             return kebiao;
118         } else {
119             return null;
120         }
121 
122     }
123     @Override
124     protected void onPostExecute(String[][] result) {
125         super.onPostExecute(result);
126         listener.onConnectFinish(result);//執行回調函數,更新主UI
127     }
128 }
129 /*
130 <table cellpadding="0" width="100%" class="displayTag" cellspacing="0" border="1" id="user">
131             <tr>
132               <td colspan="2" class="sortable">&nbsp;</td>
133               <td width="13%" class="sortable">
134                 <div align="center">星期一</div></td>
135               <td width="13%" class="sortable">
136                 <div align="center">星期二</div></td>
137               <td width="13%" class="sortable">
138                 <div align="center">星期三</div></td>
139               <td width="13%" class="sortable">
140                 <div align="center">星期四</div></td>
141               <td width="13%" class="sortable">
142                 <div align="center">星期五</div></td>
143               <td width="13%" class="sortable">
144                 <div align="center">星期六</div></td>
145               <td width="13%" class="sortable">
146                 <div align="center">星期日</div></td>
147             </tr>
148             <tr bgcolor="#FFFFFF">
149               <td width="3%" rowspan="4">&nbsp;
150                 <p class="style4">上午</p></td>
151               <td width="11%">第1節(08:00-08:45)</td>
152               <td>&nbsp; 計算機網絡A_01(西部校區綜合教學2號樓B406)
153                 <br></td>
154               <td>&nbsp; &nbsp;</td>
155               <td>&nbsp; &nbsp;</td>
156               <td>&nbsp; 編譯原理_01(校部綜合教學1號樓綜151)
157                 <br></td>
158               <td>&nbsp; 計算機組成原理_01(西部校區綜合教學2號樓B103)
159                 <br></td>
160               <td>&nbsp; &nbsp;</td>
161               <td>&nbsp; &nbsp;</td></tr>
162             <tr bgcolor="#FFFFFF">
163               <td width="11%">第2節(08:50-09:35)</td>
164               <td>&nbsp; 計算機網絡A_01(西部校區綜合教學2號樓B406)
165                 <br></td>
166               <td>&nbsp; &nbsp;</td>
167               <td>&nbsp; &nbsp;</td>
168               <td>&nbsp; 編譯原理_01(校部綜合教學1號樓綜151)
169                 <br></td>
170               <td>&nbsp; 計算機組成原理_01(西部校區綜合教學2號樓B103)
171                 <br></td>
172               <td>&nbsp; &nbsp;</td>
173               <td>&nbsp; &nbsp;</td></tr>
174             <tr bgcolor="#FFFFFF">
175               <td width="11%">第3節(10:05-10:50)</td>
176               <td>&nbsp; &nbsp;</td>
177               <td>&nbsp; 面向對象程序設計_01(西部校區綜合教學2號樓A301)
178                 <br></td>
179               <td>&nbsp; &nbsp;</td>
180               <td>&nbsp; 人工智能_01(西部校區綜合教學2號樓A101)
181                 <br></td>
182               <td>&nbsp; &nbsp;</td>
183               <td>&nbsp; &nbsp;</td>
184               <td>&nbsp; &nbsp;</td></tr>
185             <tr bgcolor="#FFFFFF">
186               <td width="11%">第4節(10:55-11:40)</td>
187               <td>&nbsp; &nbsp;</td>
188               <td>&nbsp; 面向對象程序設計_01(西部校區綜合教學2號樓A301)
189                 <br></td>
190               <td>&nbsp; &nbsp;</td>
191               <td>&nbsp; 人工智能_01(西部校區綜合教學2號樓A101)
192                 <br></td>
193               <td>&nbsp; &nbsp;</td>
194               <td>&nbsp; &nbsp;</td>
195               <td>&nbsp; &nbsp;</td>
196               <tr bgcolor="#FFFFFF">
197                 <td colspan="9">&nbsp;
198                   <p align="center" class="td2 style5">
199                     <strong>午 休</strong></p>
200                 </td>
201               </tr>
202             </tr>
203             <tr bgcolor="#FFFFFF">
204               <td width="3%" rowspan="4">&nbsp;
205                 <p class="style4">下午</p></td>
206               <td width="11%">第5節(13:30-14:15)</td>
207               <td>&nbsp; 編譯原理_01(校部綜合教學1號樓綜151)
208                 <br></td>
209               <td>&nbsp; 計算機組成原理_01(西部校區綜合教學2號樓B103)
210                 <br></td>
211               <td>&nbsp; &nbsp;</td>
212               <td>&nbsp; 計算機網絡A_01(西部校區綜合教學2號樓B406)
213                 <br></td>
214               <td>&nbsp; &nbsp;</td>
215               <td>&nbsp; &nbsp;</td>
216               <td>&nbsp; &nbsp;</td></tr>
217             <tr bgcolor="#FFFFFF">
218               <td width="11%">第6節(14:20-15:05)</td>
219               <td>&nbsp; 編譯原理_01(校部綜合教學1號樓綜151)
220                 <br></td>
221               <td>&nbsp; 計算機組成原理_01(西部校區綜合教學2號樓B103)
222                 <br></td>
223               <td>&nbsp; &nbsp;</td>
224               <td>&nbsp; 計算機網絡A_01(西部校區綜合教學2號樓B406)
225                 <br></td>
226               <td>&nbsp; &nbsp;</td>
227               <td>&nbsp; &nbsp;</td>
228               <td>&nbsp; &nbsp;</td></tr>
229             <tr bgcolor="#FFFFFF">
230               <td width="11%">第7節(15:35-16:20)</td>
231               <td>&nbsp; 人工智能_01(西部校區綜合教學2號樓A101)
232                 <br></td>
233               <td>&nbsp; &nbsp;</td>
234               <td>&nbsp; &nbsp;</td>
235               <td>&nbsp; &nbsp;</td>
236               <td>&nbsp; 面向對象程序設計_01(西部校區綜合教學2號樓A301)
237                 <br></td>
238               <td>&nbsp; &nbsp;</td>
239               <td>&nbsp; &nbsp;</td></tr>
240             <tr bgcolor="#FFFFFF">
241               <td width="11%">第8節(16:25-17:10)</td>
242               <td>&nbsp; 人工智能_01(西部校區綜合教學2號樓A101)
243                 <br></td>
244               <td>&nbsp; &nbsp;</td>
245               <td>&nbsp; &nbsp;</td>
246               <td>&nbsp; &nbsp;</td>
247               <td>&nbsp; 面向對象程序設計_01(西部校區綜合教學2號樓A301)
248                 <br></td>
249               <td>&nbsp; &nbsp;</td>
250               <td>&nbsp; &nbsp;</td>
251               <tr bgcolor="#FFFFFF">
252                 <td colspan="9">&nbsp;
253                   <p align="center" class="td2 style5">
254                     <strong>晚 飯</strong></p>
255                 </td>
256               </tr>
257             </tr>
258             <tr bgcolor="#FFFFFF">
259               <td width="3%" rowspan="4">&nbsp;
260                 <p class="style4">晚上</p></td>
261               <td width="11%">第9節(18:00-18:45)</td>
262               <td>&nbsp; 社會學*_886(校部綜合教學1號樓綜152)
263                 <br></td>
264               <td>&nbsp; 人類文明史*_887(校部材料館材101)
265                 <br></td>
266               <td>&nbsp; &nbsp;</td>
267               <td>&nbsp; &nbsp;</td>
268               <td>&nbsp; &nbsp;</td>
269               <td>&nbsp; &nbsp;</td>
270               <td>&nbsp; &nbsp;</td></tr>
271             <tr bgcolor="#FFFFFF">
272               <td width="11%">第10節(18:55-19:40)</td>
273               <td>&nbsp; 社會學*_886(校部綜合教學1號樓綜152)
274                 <br></td>
275               <td>&nbsp; 人類文明史*_887(校部材料館材101)
276                 <br></td>
277               <td>&nbsp; &nbsp;</td>
278               <td>&nbsp; &nbsp;</td>
279               <td>&nbsp; &nbsp;</td>
280               <td>&nbsp; &nbsp;</td>
281               <td>&nbsp; &nbsp;</td></tr>
282             <tr bgcolor="#FFFFFF">
283               <td width="11%">第11節(19:50-20:35)</td>
284               <td>&nbsp; 社會學*_886(校部綜合教學1號樓綜152)
285                 <br></td>
286               <td>&nbsp; 人類文明史*_887(校部材料館材101)
287                 <br></td>
288               <td>&nbsp; &nbsp;</td>
289               <td>&nbsp; &nbsp;</td>
290               <td>&nbsp; &nbsp;</td>
291               <td>&nbsp; &nbsp;</td>
292               <td>&nbsp; &nbsp;</td></tr>
293             <tr bgcolor="#FFFFFF">
294               <td width="11%">第12節(20:45-21:30)</td>
295               <td>&nbsp; &nbsp;</td>
296               <td>&nbsp; &nbsp;</td>
297               <td>&nbsp; &nbsp;</td>
298               <td>&nbsp; &nbsp;</td>
299               <td>&nbsp; &nbsp;</td>
300               <td>&nbsp; &nbsp;</td>
301               <td>&nbsp; &nbsp;</td></tr>
302           </table>
303 
304 */
View Code

 

五、關於回調函數的使用

  這一部分以前徹底沒預料到,只是後來才發現,不用內部類,想更新UI就得用回調函數,其更深層次的思想是一種設計模式,仍是本身學的太少!知識使用徹底浮於表面。

六、Demo演示

七、總結

  零零散散花了很多時間,一來確實第一次作相似工做,二來本身習慣很是很差,對於新工具,研究API和即學即用能力不強。明天應該好好研究一下HttpClientJsoup,達到熟練抓取各類網頁的目的!畢竟這只是開始!如今的學習狀態實在過低效了。

  以上。

相關文章
相關標籤/搜索