前言
記得從大二的時候就很想寫一個基于教務系統的輔助工具,提供一些“黑科技”的功能,例如輔助選課等等,但是受限于當時掌握的知識,還有就是正方的這套教務系統實在是有不少坑。。。
遇到的坑
下面總結一下在爬取數據過程中遇到的一些問題及解決方案。
1. 模擬登陸教務系統需要一個隱藏表單項
想要爬取教務系統中的課程、成績等信息,首先自然是要登錄系統,在抓包的過程中發現,提交的 POST 請求中需要一個名為 lt 的參數,查看源碼,發現一個隱藏表單項。
隱藏表單項
沒有這個參數是無法成功登錄的,因此我們需要先通過一個 GET 請求,獲取到該表單項的值,然后再進行 POST 登錄。
2. 登錄完成以及跳轉到其他應用時會有很多認證跳轉
這個是什么意思呢?當我們在完成 POST 請求之后,并不是直接跳轉至我們想要的頁面,而是會經過多次頁面跳轉。個人猜測是為了同步不同域之間的會話數據,由于整個教務系統,包括數字杭電、教學管理(選課系統)、銀校通其實都各自是獨立的應用,所屬域不同,甚至使用的編程語言都不同,那么當我們從一個應用跳轉至另一個應用的時候,如何保持我們的登錄狀態呢?首先每個應用需要提供一個接口用于同步會話信息,然后需要一個獨立的認證服務。
選課系統的地址沒有直接指向 jxgl.hdu.edu.cn,而是經過幾層跳轉最終到達目的地
當然上面都是我個人的猜測。。。
在這套系統中,這些跳轉是通過 js 來完成的(location.href = ……),那我們要怎么做的,最簡單的方式就是使用循環,檢查源碼中是否包含「認證跳轉」這四個字,如果有,則解析出其中要跳轉的地址,再發送一次 GET 請求,如果沒有,表明已經到達目的地,則退出循環。
3. 請求頁面出現 Object moved to here
Object moved to here
這個問題困擾了我很長時間,也導致這個項目荒廢了很久。
這其實是 asp.net 編寫的 Web 程序經常出現的問題,具體我也沒有深入研究,解決方案也很簡單,在請求頭加入一個 Referer 參數就可以了,值的話可以用請求頁面的 URL。