日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

用Python登陆新版正方教务系统获取课程表(及RSA加密密码实现)

發布時間:2024/3/12 windows 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用Python登陆新版正方教务系统获取课程表(及RSA加密密码实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

最近做一個微信小程序,需要登錄教務系統。提前用python嘗試一下登錄接口,并獲取到課表打印出來。

我們學校用到新版正方教務系統,長這個樣子。


相比舊版的教務系統,唯一好處是不用輸入二維碼方便爬蟲登錄。但登錄時用到RSA加密密碼發送請求。


正文

分析網頁:
在網頁上填上隨便寫的賬號密碼,點擊登錄。開發者工具記錄如下:

首先它點擊登錄后,提交一個表單,Form Data一共有4個數據

提交的數據解釋
csrftoken為了防止跨站域請求偽造 。在登錄頁源碼里有,每次刷新都會變更
yhm輸入的用戶名
mm輸入的密碼,被加密過。我們主要關注這一個加密過程

csrftoken 如圖所示:

另外,在開發者工具里,我們還需要注意服務器的一條get請求

查看它返回的數據

這條Get請求作用:發送當前時間戳,返回公共密鑰。并且每次modulus的數據不同,有人會問,這個東西干嘛的?
其實,這是在密碼加密時用到的公鑰,如果你也曾看過它的密碼加密代碼,就會了解到。
我們翻一下網站的Javascript,看看密碼加密過程

$.getJSON(_path+"/xtgl/login_getPublicKey.html?time="+new Date().getTime(),function(data){modulus = data["modulus"];exponent = data["exponent"];}); if($("#mmsfjm").val() == '0'){$("#hidMm").val($("#mm").val());}else{var rsaKey = new RSAKey();rsaKey.setPublic(b64tohex(modulus), b64tohex(exponent));var enPassword = hex2b64(rsaKey.encrypt($("#mm").val()));$("#mm").val(enPassword);$("#hidMm").val(enPassword); }

具體加密過程:首先獲取modulus,exponent。將他們從base64轉16進制,再通過RSA算法生成公鑰。
用公鑰將密碼生成私鑰從16進制轉回base64。變成最終加密的密碼。

至此,我們分析完成,在python里面要做的步驟:
1、獲取到csrftoken
2、發送時間戳獲取到PublicKey
3、生成RSA加密的密碼
4、POST請求登錄


python實現過程

登錄中唯一難點是生成rsa加密的密碼,有大神把js的rsa算法寫成python,具體在github里。我已經下載并放在項目文件夾下,直接調用。

頭部文件:

import requests import time from lxml import etree from hex2b64 import HB64 import RSAJS

重中之重的RSA加密過程:

def Get_RSA_Password(self):# 生成RSA加密密碼rsaKey = RSAJS.RSAKey()rsaKey.setPublic(HB64().b642hex(self.modulus),HB64().b642hex(self.exponent))self.enPassword = HB64().hex2b64(rsaKey.encrypt(self.Password))

與JavaScript原加密算法對比:

登錄代碼:

def Longin_Home(self):# 登錄信息門戶,成功返回session對象self.Get_indexHtml()self.Get_csrftoken()self.Get_PublicKey()self.Get_RSA_Password()login_data = [("csrftoken", self.csrftoken),("yhm", self.Username),("mm", self.enPassword),("mm", self.enPassword)]login_html = self.session.post(self.login_url + self.now_time,data=login_data)# 當提交的表單是正確的,url會跳轉到主頁,所以此處根據url有沒有跳轉來判斷是否登錄成功if login_html.url.find("login_slogin.html") == -1: # -1沒找到,說明已經跳轉到主頁print("登錄成功")return self.sessionelse:print("用戶名或密碼不正確,登錄失敗")exit()

獲取課程表代碼

class TimeTable():def __init__(self,session,table_url):data = {"xnm":2018,"xqm":12}table_info = session.post(table_url,data = data).json()for each in table_info["kbList"]:plt = r'{} | {:<8s} | {:<13s} | {:<15s} | {:<22s}'print(plt.format(each["xqjmc"], each["jc"], each["cdmc"], each["zcd"], each["kcmc"]))

登錄成功后已經可以為所欲為了,獲取課程表只是一個簡單操作,就沒怎么優化代碼了。

完整代碼:

# -*- coding=utf-8 -*- import requests import time from lxml import etree from hex2b64 import HB64 import RSAJSclass Longin():def __init__(self,user,password,login_url,login_KeyUrl):# 初始化程序數據self.Username = userself.Password = passwordnowTime = lambda:str(round(time.time()*1000))self.now_time = nowTime()self.login_url = login_urlself.login_Key = login_KeyUrldef Get_indexHtml(self):# 獲取教務系統網站self.session = requests.Session()self.session.headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36","Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","Accept-Encoding": "gzip, deflate","Accept-Language": "zh-CN,zh;q=0.9","Cache-Control": "max-age=0","Connection": "keep-alive","Referer": self.login_url+ self.now_time,"Upgrade-Insecure-Requests": "1" })self.response = self.session.get(self.login_url+ self.now_time).content.decode("utf-8")def Get_csrftoken(self):# 獲取到csrftokenlxml = etree.HTML(self.response)self.csrftoken = lxml.xpath("//input[@id='csrftoken']/@value")[0]def Get_PublicKey(self):# 獲取到加密公鑰key_html = self.session.get(self.login_Key + self.now_time)key_data = key_html.json()self.modulus = key_data["modulus"]self.exponent = key_data["exponent"]def Get_RSA_Password(self):# 生成RSA加密密碼rsaKey = RSAJS.RSAKey()rsaKey.setPublic(HB64().b642hex(self.modulus),HB64().b642hex(self.exponent))self.enPassword = HB64().hex2b64(rsaKey.encrypt(self.Password))def Longin_Home(self):# 登錄信息門戶,成功返回session對象self.Get_indexHtml()self.Get_csrftoken()self.Get_PublicKey()self.Get_RSA_Password()login_data = [("csrftoken", self.csrftoken),("yhm", self.Username),("mm", self.enPassword),("mm", self.enPassword)]login_html = self.session.post(self.login_url + self.now_time,data=login_data)# 當提交的表單是正確的,url會跳轉到主頁,所以此處根據url有沒有跳轉來判斷是否登錄成功if login_html.url.find("login_slogin.html") == -1: # -1沒找到,說明已經跳轉到主頁print("登錄成功")return self.sessionelse:print("用戶名或密碼不正確,登錄失敗")exit()class TimeTable():def __init__(self,session,table_url):data = {"xnm":2018,"xqm":12}table_info = session.post(table_url,data = data).json()for each in table_info["kbList"]:plt = r'{} | {:<8s} | {:<13s} | {:<15s} | {:<22s}'print(plt.format(each["xqjmc"], each["jc"], each["cdmc"], each["zcd"], each["kcmc"]))if __name__ == "__main__":# 登錄主頁urllogin_url = "http://學校主頁/jwglxt/xtgl/login_slogin.html?language=zh_CN&_t="# 請求PublicKey的URLlogin_KeyUrl = "http://學校主頁/jwglxt/xtgl/login_getPublicKey.html?time="# 登錄后的課表URLtable_url = "http://學校主頁/jwglxt/kbcx/xskbcx_cxXsKb.html?gnmkdm=N2151"zspt = Longin("輸入你的賬號","輸入你的密碼",login_url,login_KeyUrl)response_cookies = zspt.Longin_Home()table = TimeTable(response_cookies,table_url)


最后需要注意的地方:
為了代碼更有移植性,方便各位在自己的學校的教務系統登錄,整個代碼幾乎封裝好了。也即是說,只要你的學校也使用新版正方教務系統,那么稍微閱讀代碼(特別是if "__name__"==__main__:這部分),改三個網站地址便可調用。

程序里調用的hex2b64、RSAJS庫和完整代碼我已經打包好了,上傳到csdn里。或者你也可以在評論留下郵箱,看到了就發給你。



CSDN下載鏈接:

https://download.csdn.net/download/koevas/11010479

百度云:

鏈接:https://pan.baidu.com/s/1gkMXCzXdx5NWUUs8bvGM-A
提取碼:it2x



參考資料:

https://github.com/Pusnow/pyjsbn-rsa
https://blog.csdn.net/qq_33278884/article/details/80936714
https://www.v2ex.com/t/433971





總結

以上是生活随笔為你收集整理的用Python登陆新版正方教务系统获取课程表(及RSA加密密码实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。