標籤:

圖書館預約工具實戰(一):建立通訊

主要內容:如何模擬手機APP與圖書館預約伺服器建立通訊。


在開始之前,請確保你已經準備好:

  • Python 3.5 或以上;
  • 一個順手的編輯器 / IDE,如PyCharm、Sublime Text;
  • Python基本語法知識(傳送門:廖雪峰的Python教程)。

這篇教程適用於利昂圖書館空間預約系統,目前應用於武漢大學等高校(傳送門:使用該系統的高校)。


一、如何開始?

首先,我們需要明確為什麼刷座腳本可以幫我們刷到座位:

  • 刷座腳本發出與APP順序、內容一致的網路請求,而非直接篡改目標系統內的數據(該行為有極大的技術和法律風險);
  • 由於腳本完成這些網路請求的速度遠快於手工操作,因此在座位需求旺盛的時候,我們能夠搶到心儀的座位;
  • 這也是網路上各種刷票、秒殺腳本的主要功能。

那麼接下來的工作就很明確了:

  • 我們需要了解APP與伺服器之間是如何通信的,也就是知道那些數據包都長什麼樣;
  • 完全模仿這些數據包的格式,與伺服器建立通訊。

於是,我們需要抓包工具來查看APP與伺服器之間的交互過程,由於我手邊只有一台Android設備,所以下文都以Android版的Packet Capture為例進行展示。

在抓包之前,我們來複習一下通過正常渠道預約一個圖書館的座位,有哪些步驟:

  • 登錄圖書館預約APP
  • 選擇對應的樓棟、房間、座位
  • 選擇預約時間
  • 收到預約成功的提示信息

二、查看數據包

我們先從登錄開始。打開 Packet Capture 的監控,再使用APP進行登錄。查看剛剛抓下的數據包。

圖1-1 登錄數據包

可以發現:

APP在登錄時,向 seat.lib.whu.edu.cn/res 發送了一個GET數據包,參數包括:username(學號),password(密碼);

  • 返回的數據包是JSON格式,包含了請求是否成功,以及一個數據欄位token;
  • 進一步查看其它數據包時,發現學號和密碼已經不再存在於數據包中,而登錄後的每個數據包中都存在token欄位(如圖1-2)。

圖1-2 當前預約情況數據包

這個token欄位是做什麼用的呢?(百度 / Google 一下,你就知道)

  • token的意思是令牌,是目前廣泛使用的一種後台認證機制;
  • 在登錄的過程中,用戶用自己的用戶名和密碼,向伺服器換取token(令牌),作為自己之後與伺服器交互的身份憑證;
  • 這麼做的優點,可以繼續百度 / Google 一下。因為和本文目標無關,此處不再贅述。

OK,到此為止,我們需要先解決token這塊攔路石。


三、模擬登陸

考慮到:

  • 圖書館伺服器返回的都是JSON格式的消息,可以用python的json.loads()方法進行解析
  • 網路請求除了路徑參數有不同以外,其他都大致相同

因此我們可以將網路請求的內容封裝成一個方法:

import urllib.parse, urllib.request, jsondef get_json_tree(request_url, request_para): # requestPara中的key名需要與圖書館系統要求的一致 # 觀察到login請求中參數是附在URL之後的,因此使用urlencode方法對參數進行編碼, # 並加入到URL之後 url = request_url + ? + urllib.parse.urlencode(request_para) req = urllib.request.Request(url) res = urllib.request.urlopen(req) message = res.read() # 讀取返回的消息 json_tree = json.loads(message.decode("utf-8")) # 解析 return json_tree # 返回解析的dict類型

我們利用這個方法進行模擬登陸:

lib_website = http://seat.lib.whu.edu.cn/json_tree = get_json_tree(lib_website + "rest/auth", { username: 2014xxxxxxxxx, password: xxxxxx })print(json_tree)print(json_tree[data][token])

測試運行結果:

> python3 main.py{status: success, data: {token: 0V6Z5N9K7E11260243}, code: 0, message: }0V6Z5N9K7E11260243

OK,我們成功地獲得了token。


四、抓取信息

接下來我們可以利用token獲取我們想要的數據了,比如要獲取之前提到的,當前預約狀態,我們可以:

lib_website = http://seat.lib.whu.edu.cn/json_tree = get_json_tree(lib_website + "rest/auth", { username: 2014xxxxxxxxx, password: xxxxxx })token = json_tree[data][token]json_tree = get_json_tree(lib_website + "rest/v2/user", { token: token })print(json_tree)

運行:

{status: success, data: {id: 231, enabled: True, name: 黃瀲哲, username: 2014xxxxxxxxx, username2: None, status: NORMAL, lastLogin: 2017-11-25T09:09:11.000, checkedIn: False, lastIn: None, lastOut: None, lastInBuildingId: None, lastInBuildingName: None, violationCount: 6}, message: , code: 0}

其他信息的獲取方法是一致的,都是先在抓包軟體中查看數據包的格式,然後再用相同的格式與伺服器建立通訊。這裡就不再贅述了。


五、小結

模擬APP與預約伺服器建立通訊的步驟:

  • 利用抓包軟體觀察數據包格式
  • 以相同的數據包格式向伺服器發送網路請求
  • 解析返回的數據包,獲得需要的信息

下一篇文章的主要內容:

  • 如何提交預約座位的請求表單,表單內的一些信息從何處獲取?
  • 如何在晚上22:30伺服器開放次日預約時立刻將請求發送出去?

推薦閱讀:

OpenCV:圖片操作基本知識
介面自動化測試的最佳工程實踐(ApiTestEngine)
用Pyador進行『異常檢測』: 開發無監督機器學習工具庫(一)
Python爬蟲聯想詞視頻和代碼
python生成器處理大文本文件的代碼

TAG:Python | 編程 |