這是在博客園裏開博以來寫的第一篇博客。html
由於以前看過不少人都有發過關於模擬登陸正方軟件獲取數據的文章,本身以爲挺好玩的便也去動手一作,開始還覺得挺難的,但實際作起來還蠻簡單的,固然其中還有些小插曲。瀏覽器
廢話很少說,先po兩張效果圖:工具
界面作得比較隨意,有空會再完善的。post
接下來便說說是如何實現的了。學習
首先,你得有個抓包工具(其實用瀏覽器自帶的f12工具應該也是能夠的,就是比較麻煩),不少人都是用Httpwatch(貌似支持IE跟火狐),這裏我就隨波逐流,也用Httpwatch。安裝好Httpwatch以後即可以直接打開瀏覽器登陸教務系統抓包啦測試
在點擊登陸按鈕的時候記得先點擊記錄。spa
登陸進去以後即可以看到Httpwatch中有數據變化了。pwa
這時先選中方法爲Post的這一行(記下此時的URL,後面有用到),再選中Post數據來看看要提交的表單有哪些。code
這裏面咱們只要用到上面圈出的五個參數。orm
第一個參數「_VIEWSTATE」要本身得到(獲取登陸首頁的html內容而後在裏面提取就好了);
第二個參數RadioButtonList1的亂碼數值實際上是「學生」(有的Httpwatch版本能夠顯示,有的則是亂碼),提交表單時提交「學生」便可;
第三個參數TextBox2是密碼;
第四個參數txtSecretCode是登陸界面的驗證碼,有的學校系統能夠直接繞過,我學校的則不行(開始看了別人的說能夠直接填空寫死,結果在這裏被坑了很久,最後只能老老實實把驗證碼加上去),因此具體可不能夠還得本身試試;
第五個參數是學號;
(每一個學校提交的參數應該都是不一樣的,不過依葫蘆畫瓢就好了)
其實表單中還有一個更重要的參數:Cookie
Cookie的值在每一次提交的時候都得加上去,Cookie同「_VIEWSTATE」同樣得本身先得到,不過不同的是Cookie獲取一次就能夠,但「_VIEWSTATE」必須每次提交都得獲取一次。
如今就來提交表單嘗試登陸
String URL = "http://jwgl.gdut.edu.cn/default2.aspx";//上面說到的URL HttpPost mHttpPost = new HttpPost(URL);//創建鏈接 mHttpPost.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, false);//禁止重定向 mHttpPost.setHeader("Cookie", Cookie);//設置Cookie //填寫表單 List<NameValuePair> list = new ArrayList<NameValuePair>(); list.add(new BasicNameValuePair("__VIEWSTATE",viewstate)); list.add(new BasicNameValuePair("txtUserName",學號)); list.add(new BasicNameValuePair("TextBox2", 密碼)); list.add(new BasicNameValuePair("RadioButtonList1","學生")); list.add(new BasicNameValuePair("txtSecretCode", 驗證碼)); //下面幾個都直接填空寫死便可(事實上下面幾個只需添加Button1便可) list.add(new BasicNameValuePair("Button1", "")); list.add(new BasicNameValuePair("lbLanguage", "")); list.add(new BasicNameValuePair("hidPdrs", "")); list.add(new BasicNameValuePair("hidsc", "")); mHttpPost.setEntity(new UrlEncodedFormEntity(list, "GBK"));//提交表單 HttpResponse mHttpResponse = new DefaultHttpClient().execute(mHttpPost);// 響應請求 int statusCode = mHttpResponse.getStatusLine().getStatusCode();//狀態碼若爲200則表示登陸失敗,此時需檢查是否表單有誤;若狀態碼爲302則表示成功
當上述狀態碼爲302時可繼續往下,若爲200請繼續檢查測試。
實際上要用到的地址是剛剛302下面的跳轉的地址
咱們再來對它創建鏈接嘗試登陸
String URL = "http://jwgl.gdut.edu.cn/xs_main.aspx?xh=" + 學號; HttpPost mHttpPost = new HttpPost(URL);//這裏用post跟get均可以 //這裏要比上次多添加一個值「Referer」,即將它的值置爲此時的URL地址 mHttpPost.setHeader("Referer", URL); mHttpPost.setHeader("Cookie", Cookie);//Cookie仍是原來的值 HttpResponse mHttpResponse = new DefaultHttpClient().execute(mHttpPost);//響應請求 //此時的狀態碼若爲200則表示成功登陸進入教務系統 if (httpResponse.getStatusLine().getStatusCode() == 200) { HttpEntity mHttpEntity = mHttpResponse.getEntity(); String html = EntityUtils.toString(mHttpEntity);//獲取網頁內容 String studentName = Jsoup.parse(html).getElementById("xhxm").text();//獲取學生名字,後面查詢成績時須要用到 }
登陸成功以後再回到瀏覽器先把剛剛抓取的數據清空,再從新點擊記錄,再進行成績的查詢,即可以抓取到數據了
一樣咱們找到方法爲Post的這一行,選中它,同時記下它的URL,一樣再在下面選中Post數據來看看須要提交的表單
這時咱們須要提交的參數有上面四個,
第一個參數「_VIEWSTATE」一樣須要本身從新得到(注意,這裏的參數已經跟上面的不同了,此時應該獲取的是登陸成功後的頁面的html內容,而後再提取便可);
第二個參數Button1又亂碼了,其實是剛剛三個按鈕的值
第三個參數ddlXN是學年;
第四個參數ddlXQ是學期;
(在這裏若是點擊按學期查詢,那麼就必須提交第三個跟第四個參數;若是點擊按學年查詢,那麼就必須提交第三個參數;若是點擊在校學習成績查詢,那麼第三個跟第四個參數都不用提交,因此咱們能夠在代碼中加個判斷)
接下來咱們用已有的參數來創建鏈接:
String URL = "http://jwgl.gdut.edu.cn/xscj.aspx?xh=" + 學號 + "&xm=" + 學生姓名 + "&gnmkdm=N121605";//學生姓名就是上面獲取到的studentName HttpPost mHttpPost = new HttpPost(URL); //填寫表單 List<NameValuePair> list= new ArrayList<NameValuePair>(); list.add(new BasicNameValuePair("__VIEWSTATE", viewstate)); list.add(new BasicNameValuePair("Button1", "按學期查詢"));//這裏我用學期查詢,所以須要添加下面兩個參數 list.add(new BasicNameValuePair("ddlXN", "2014-2015")); list.add(new BasicNameValuePair("ddlXQ", "1")); mHttpPost.setEntity(new UrlEncodedFormEntity(params, "GBK"));//提交表單 //這裏咱們一樣須要設置兩個頭信息。後面的套路跟前面的是差很少的 mHttpPost.setHeader("Referer", "http://jwgl.gdut.edu.cn/xs_main.aspx?xh=" + 學號); mHttpPost.setHeader("Cookie", Cookie); HttpResponse mHttpResponse = new DefaultHttpClient().execute(mHttpPost); HttpEntity mHttpEntity = mHttpResponse.getEntity(); String html = EntityUtils.toString(mHttpEntity);//此時就獲取到含有成績信息的頁面了 //用Jsoup將裏面的課程成績提取出來 Elements mElements = Jsoup.parse(html).select("td"); //再根據須要向mElements中提取須要的數據,再將其添加到listview中就大功告成了
固然,實現了成績查詢,其餘的功能像什麼課表查詢、考試查詢也均可以一一實現了,原理都是差很少的。