課程表的實現(基於強智科技教務系統)
課程表的實現(基於強智科技教務系統)
1,本小系統服務於在校大學生。使用者可以根據程式碼定製安裝自己的輕量級課程表app在手機上(當然,可以把網路請求部分修改移植到PC或者Web平臺上)。
2,好處:再也不用為了在手機上看課表而專門去下載30~60MB不等大小並且有各種干擾資訊的APP了。 同時,許多教務系統只能用IE登陸,是否讓人惱火?
3,這裡嘗試做個簡單的課表查詢小程式(Android)。當然對於這裡所提到的網路請求都清楚了,可以實現更多基於教務系統周邊更有意思的應用。
4,原始碼可以在github上檢視,如有任何疑問,可以issue,也可以@我[email protected]
閱讀前
-
在閱讀本文章,程式碼的時候假定你已經對 HTTP的GET,POST 有基本的認識。知道 HTML的form 表單幹什麼用。
-
對基於 “強智科技教務系統” 的同學友好。因為他們做的登陸介面,查詢介面相差不大。我找了幾個跟本校教務系統介面差不多的系統,查看了 驗證碼介面,登陸介面 。發現幾乎沒什麼變化。所以我猜內部的課表介面是重用的一套程式碼。
下面是我找到的跟本校的教務系統同一風格並且驗證碼介面,登陸介面一樣的教務系統介面截圖。(至於內部課表的介面我就不知道是否跟本校的介面格式一致,大傢俱體情況具體分析)
當然這個登陸介面也類似啦
-
當然對於非 “強智科技教務系統” 的同學來說,也很容易根據程式碼分析,然後寫出適合自己學校的課表檢視小程式。
-
程式碼重在分析網路請求,篩選重要資訊。 這是任何人都能學到的知識。
原始碼說明
本程式碼最終資料呈現平臺為 Android ,在解析介面,獲得資料過程中會講解怎麼將其呈現在介面上。當然你也可以做基於web,PC端的。
程式碼仍有不足,後續會更新,可持續關注喲:學期靈活切換;驗證碼識別。
有任何問題可以@我,[email protected]
程式碼模組解析
1. 網路請求
教務系統登陸通用 三要素 :賬號,密碼,驗證碼
有了所述的三要素,我們就可以進入教務系統進行各項操作啦。下面是分析網路請求。
開啟瀏覽器(這裡我們用Chrome瀏覽器,當然firefox也有類似的如下操作),進入教務網登陸介面,按F12彈出 開發者工具 點選 Network ,再在最左側點選教務網的 請求路徑名 ,可以看到Request Headers(請求頭)。(如果點選Network什麼都看不到那就在開發者工具開啟的前提下重新整理一下教務網就行了)。請求頭裡 最重要 的當然是 Cookie 啦。
Cookie在這裡作為登陸的唯一標識。也就是說,你登陸後,把Cookie儲存下來,使用這個Cookie(存活期內)能夠訪問這個教務系統下的任意地址的網頁,資料。
下面可以做個小實驗驗證這個觀點,這個實驗理解了,後面程式的 模擬登陸教務網 也可以理解了。
假定我的 教務網地址 是: kk.edu.cn/jww/ ,我登陸成功並且 跳轉地址 到 kk.edu.cn/jww/framework/main.jsp ,複製成功登陸時用的Cookie值。在瀏覽器上開啟一個新標籤頁,輸入 教務網地址 : kk.edu.cn/jww/ ,此時(一般情況)是沒有登陸的,我們再次開啟開發者工具,這次不點選Network了,我們點選 Application ,雙擊Cookie值,修改它為我們之前登陸的Cookie值(如下圖),再把本標籤頁位址列的地址換為登陸後我們想訪問的地址(比如說登陸後跳轉的地址)並回車!我們已經算是登陸教務系統並且進入系統了!
下面是登陸教務網的核心程式碼。
Connection loginConn = Jsoup.connect(loginHomePage);
loginConn.cookies(cookies); //login using cookies
loginConn.data(reqData); //login parameters
Connection.Response loginResponse = loginConn.execute();
說明:Jsoup庫很簡單,並且在這裡用的不多,通過程式碼說明很容易理解。
loginHomePage為教務網 form的action 屬性值(檢視原始碼可以看到),也就是我們表單要提交的url地址。
如果我們直接看程式碼第四行,把而三行註釋掉,獲得一個Response,我們可以直接打印出loginResponse的內容,全部為HTML程式碼,根本沒有圖片。也就是說, 我們得單獨請求圖片,並且儲存請求圖片返回的Cookie,並且登陸時使用這個Cookie來登陸。
現在思路就是:我們想要登陸,就得先請求並下載驗證碼圖片,獲取請求圖片時返回的Cookie,並且用這個Cookie加上我們自己填寫的賬號,密碼,和根據下載的圖片填寫的驗證碼,把這些引數一併提交給伺服器進行登陸。
於是我們可以完善我們的程式碼:
//all static for convenience
//file request parameters
static String personType = "0"; //0-我是學生, 1-我是家長。 很多教務網都沒有這個欄位,可忽略掉
static String userNumber = "****"; //你的賬號
static String password = "****"; //你的密碼
static String verifyCode = ""; //驗證碼預設設定為空,後續通過使用者的輸入來填充這個值
//登陸請求的地址
final static String loginHomePage = "http://kkk.edu.cn/jww/Logon.do?method=logon";
//驗證碼請求地址
final static String verifyImgSrcURL = "http://kk.edu.cn/jww/verifycode.servlet";
//驗證碼儲存的桌面位置
final static String verifyImgDestURL = "C:\\Users\\Liture\\Desktop\\verifyCodeImg.jpg";
課表的地址
final static String getTableBaseURL = "http://kkk.edu.cn/jww/tkglAction.do?method=goListKbByXs";
//cookie name
final static String sessionName = "JSESSIONID";
//cookie value
static String sessionValue = "";
//request parameters [personType, username, password, RANDOMCODE]
static Map<String, String> reqData = new HashMap<>();
static Map<String, String> cookies = new HashMap<>(); //save cookies
// 'reqData' initialization
static {
reqData.put("personType", personType); // 0 - students or teachers , 1 - parents
reqData.put("USERNAME", userNumber);
reqData.put("PASSWORD", password);
}
public static void main(String[] args) throws IOException {
//download verifyImg and
//get the cookie we getfrom the img
//use the cookie everywhere around the site.
downloadImgReturnCookie(verifyImgSrcURL, verifyImgDestURL);
System.out.println("Download Image Successfully");
//print cookie
System.out.println(cookies);
//input verifycode
System.out.print("Please input your verifyCode: ");
verifyCode = new Scanner(System.in).nextLine();
reqData.put("RANDOMCODE", verifyCode);
//login using cookie prepared.
Connection loginConn = Jsoup.connect(loginHomePage);
//login using cookies
loginConn.cookies(cookies);
//login parameters
loginConn.data(reqData);
//try to login
Connection.Response loginResponse = loginConn.execute();
System.out.println( loginResponse.body() );
//。。。未完,看下面分析
}
// download verifyCode image from 'srcUrl' and save to 'dest' at localhost
private static void downloadImgReturnCookie(String srcUrl, String dest) throws MalformedURLException, IOException{
//get image using the cookie
HttpURLConnection imgConn = (HttpURLConnection) ( new URL(srcUrl) ).openConnection();
//get the cookie
String cookie = imgConn.getHeaderField("Set-Cookie");
sessionValue = cookie.substring( cookie.indexOf('=') + 1, cookie.indexOf(';') );
cookies.put( sessionName, sessionValue );
//new input from network( 'imgConn' )
try( BufferedInputStream imgInputStream = new BufferedInputStream( imgConn.getInputStream() ) ){
//new output to local file system
try( BufferedOutputStream imgOutputStream = new BufferedOutputStream( new FileOutputStream(dest) ); ){
byte[] buf = new byte[1024];
while( -1 != ( imgInputStream.read(buf) ) )
imgOutputStream.write(buf);
} catch(IOException e) { e.printStackTrace(); }
} catch(IOException e) { e.printStackTrace(); }
}
程式碼先呼叫downloadImgReturnCookie(verifyImgSrcURL, verifyImgDestURL);
請求驗證碼圖片,並且儲存到桌面,於此同時把返回的Cookie儲存起來。再通過new Scanner(System.in).nextLine()
獲取使用者輸入的驗證碼(下載到桌面了自己很容易開啟並且肉眼識別了)。
最後登入,列印登陸請求返回的HTML原始碼。
我們發現,當我們輸入了錯誤的驗證碼(或者賬號或密碼錯誤)的時候,打印出來的是登陸介面的HTML原始碼,當我們登陸成功的時候,返回的內容很簡單:<script language='javascript'>window.location.href='http://kk.edu.cn/jww/framework/main.jsp';</script>
。據此我們很容易判斷我們是否登陸成功了。
以上是網路請求的全部分析過程。
更多的將資料呈現在Android平臺上可以檢視原始碼。同時可以檢視下面的效果圖。