Python實現(xiàn)全自動校園網(wǎng)認證與登錄腳本
一、項目背景
在現(xiàn)代大學生活中,穩(wěn)定且高效的網(wǎng)絡連接是學生日常學習和生活的重要組成部分。然而,許多學校的校園網(wǎng)需要通過網(wǎng)頁認證登錄,這不僅繁瑣而且耗時。為了簡化這一過程,我開發(fā)了一個自動化腳本,旨在幫助學生自動連接到校園網(wǎng),無需手動操作。
校園網(wǎng)使用痛點
- 設備重啟后需要重新認證
- 網(wǎng)絡波動導致頻繁掉線
- 實驗室設備需長期保持在線
傳統(tǒng)解決方案的不足
- 瀏覽器保存密碼存在安全風險
- 第三方工具可能攜帶廣告/后門
- 無法自定義檢測頻率和策略
二、腳本核心功能
功能模塊 | 實現(xiàn)方式 | 技術亮點 |
---|---|---|
網(wǎng)絡狀態(tài)檢測 | 定時請求認證頁面+標題解析 | 雙編碼兼容(GBK/UTF-8) |
自動認證系統(tǒng) | 模擬瀏覽器POST請求 | 請求頭指紋偽裝 |
桌面通知提醒 | win10toast庫 | 非阻塞式彈窗 |
運行日志系統(tǒng) | 文件寫入+自動清理 | 日志輪轉機制 |
智能休眠策略 | 隨機間隔檢測 | 防模式識別 |
三、校園網(wǎng)認證邏輯分析
1.先登錄校園網(wǎng)認證網(wǎng)頁,點擊F12,選中網(wǎng)絡并勾選保存日志
2.再輸入賬戶密碼,點擊連接login,進行抓包(一般netword的前幾個比較重要,后面的都是資源文件)
3.這里發(fā)現(xiàn)發(fā)了兩個請求,第一個post請求,第二個get請求(每個學校的不一樣,HHU的可以直接用本教程方法)
第一個是post請求
點擊payload查看post請求攜帶的數(shù)據(jù),發(fā)現(xiàn)里面包含了自己的校園網(wǎng)賬戶和密碼
第二個是get請求,復制上面的request URL到瀏覽器,發(fā)現(xiàn)就是可以訪問的認證界面。
小結:點擊login按鈕后,密碼是先通過一個post請求提交到服務器,然后再通過一個get請求去實現(xiàn)登錄的。
那腳本要做的事情就是:當發(fā)現(xiàn)當前處于未登錄狀態(tài)時,要模擬瀏覽器的行為,先發(fā)一個post請求,請求header和data都要和瀏覽器上的內容對應,然后再發(fā)一個get請求就可以了。
如何判斷當前是否處于未登錄狀態(tài)?
一般提交get請求時,當前已經登錄和為登錄狀態(tài)得到html文檔中的標簽內容是不一樣的。這里我們在已登錄狀態(tài)下,按F12,再按ctrl+F查找下的內容,發(fā)現(xiàn)果然有標識
四、代碼解析(關鍵部分)
核心模塊
HTTP請求:使用requests庫發(fā)送HTTP請求,與校園網(wǎng)認證服務器進行通信。
HTML解析:使用re模塊解析HTML內容,提取標題元素以判斷登錄狀態(tài)。
Windows通知:使用win10toast庫顯示桌面通知。
日志記錄:將每次操作的結果記錄到日志文件中。
異常處理:捕獲并處理各種可能的異常情況,確保腳本的穩(wěn)定性。
代碼結構
1.寫一個死循環(huán),不斷判斷當前是否處于登錄狀態(tài):直接發(fā)get請求,如果返回的tittle為“登錄成功”,則為已登錄狀態(tài)。
while(True): print("自動聯(lián)網(wǎng)腳本開始運行...") # 請求校園網(wǎng)url response = request.urlopen(get_URL) html = response.read() # 獲取tittle元素內容 res = re.findall('<title>(.*)</title>', html.decode(encoding="GBK", errors="strict")) print('res:', res) title = '' if len(res) == 0: print("訪問",get_URL,"失敗,請檢查請求地址!") pass else: title = res[0] print("title:",title)
2.否則的話,就模擬瀏覽器的行為,給服務器發(fā)一個post請求(設置好header和data,示例如下),然后再發(fā)一個get請求進行認證。
設置header操作如下:查看請求一Headers,鼠標向下滑,找到Request Header,將自己的配置復制到代碼相對應的配置中。
# 設置post的請求頭,瀏覽器點擊F12,在Netword中選中post請求,點擊Headers、request header面板中查看 header = { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7", "Connection": "keep-alive", "Content-Length": "762", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Cookie": "EPORTAL_COOKIE_DOMAIN=false; EPORTAL_COOKIE_USERNAME=XXXXX; EPORTAL_COOKIE_SERVER=%E4%B8%AD%E5%9%E7%A7%BB%E5%8A%A8(CMCC%20NET); EPORTAL_COOKIE_SERVER_NAME=%E4%B8%AD%E5%9B%BA7%BB%E5%8A%A8(CMCC%20NET); EPORTAL_COOKIE_SAVEPASSWORD=true; EPORTAL_COOKIE_OPERATORPWD=; EPORTAL_COOKIE_NEWV=true; EPORTAL_COOKIE_PASSWORD=1e485d5861f50092df261f37ca6218c4d8675e6daf226f84489f5bd7ca8339a4e15b27b2fdb3a1ade55b553c96a04a76ad00a31cb46902d356babec2ced138dc40f97b6f5b489274aa5561d24a6f9610caf99e52e5a0d92bf2448819f44dfc2f2c37966d8554aa00fe530d0cbe52a0d4438f2640f04410e865ff3aeff6faf9ff; EPORTAL_AUTO_LAND=; EPORTAL_USER_GROUP=%E5%AD%A6%E7%94%9F; JSESSIONID=8A3372E32254B5F7321DF7B93A4851AA; JSESSIONID=F2C1BB4E6D58762763F36630541B5C38", "Host": "eportal.hhu.edu.cn", "Origin": "http://eportal.hhu.edu.cn", "Referer": "http://eportal.hhu.edu.cn/eportal/index.jsp?wlanuserip=29fc0b608918b04682c9e6c6cf6c1c29&wlanacname=2356e8aa38c836625d91257381aaef57&ssid=ea65e712d7d12a1fb44ec48a1c5072b0&nasip=07ec241dffc0de15d87efe9c07b8c6e0&mac=027a460789bb1e7c9c4acc766c937e6e&t=wireless-v2&url=35e6780db7fde27a90f8986393791ca7b01578112b560bd2", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36", }
設置data
# 設置post的請求數(shù)據(jù),瀏覽器點擊F12,在Netword中選中post請求,點擊payload面板中查看 data = { "userId": 'XXX', # 需要根據(jù)自己的情況修改 "password": '1e485d5861f50092df261f37ca621daf226f84489f5bd5b27b2fdb3a1ade55b553c96a04a76ad00aa31cb4ced138dc40f97b6f5b489274a6f9610caf99e52e5a0d92bf2448819f44dfc2f2c37966d8554ada00fe530d0cbe52a0d4438f2640f04410e865ff3aeff6faf9ff', # 需要根據(jù)自己的情況修改 "queryString": 'wlanuserip%3D29fc0b608918b04682c9e6c6cf6c1c29%26wlanacname%3D2356e8aa38c836625d91257381aaef57%26ssid%3Dea65e712d7d12a1fb44ec48a1c5072b0%26nasip%3D07ec241dffc0de15d87efe9c07b8c6e0%26mac%3D027a460789bb1e7c9c4acc766c937e6e%26t%3Dwireless-v2%26url%3D35e6780db7fde27a90f8986393791ca7b01578112b560bd2', "passwordEncrypt": 'true', "operatorPwd": '', "operatorUserId": '', "validcode": '', "service": '', }
3.打印狀態(tài)碼,判斷是否認證成功。
4.休眠一段時間,然后進行下一次循環(huán)。
# 每1h左右檢測一次是否成功連接 rand = random.uniform(0, 100) print("休眠",int(3600.0 + rand),"s") time.sleep(3600.0 + rand)
另外,由于這個腳本可以放到需要后臺運行,把日志輸出到log文件中去,可以查看腳本運行狀態(tài)。
以下是腳本的主要部分:
import urllib.request from urllib import parse import time import random import os import re # 設置日志文件路徑 log_file_path = 'log.txt' # 第一個post請求的URL post_URL = 'http://10.100.255.2/eportal/InterFace.do?method=login' # 第二個get請求的URL(瀏覽器可訪問的url) get_URL = 'http://10.100.255.2/eportal/success.jsp?userIndex=63360363366306533343048342464646&keepaliveInterval=0' while True: print("自動聯(lián)網(wǎng)腳本運行中...") try: # 請求校園網(wǎng)url(添加超時防止阻塞) response = urllib.request.urlopen(get_URL, timeout=10) html = response.read() except Exception as e: print(f"網(wǎng)絡請求異常: {e}") html = b'' # 防止html未定義 # 獲取title元素內容 res = re.findall('<title>(.*)</title>', html.decode(encoding="GBK", errors="ignore")) # 使用errors="ignore"避免解碼失敗 print('res:', res) title = '' if len(res) == 0: print(f"訪問 {get_URL} 可能未連接到校園網(wǎng)!") else: title = res[res[0]] # 根據(jù)title判斷登錄狀態(tài) if title == '登錄成功': print('當前狀態(tài)為:已登錄!') # 彈出Windows通知 # try: # toaster.show_notification( # "校園網(wǎng)狀態(tài)", # "✅ 已成功連接到校園網(wǎng)!", # duration=5, # icon_path="school.ico", # 可替換為圖標路徑如 "school.ico" # threaded=True # ) # except Exception as e: # print(f"通知發(fā)送失敗: {e}") else: print('當前狀態(tài)為:未登錄!') # 設置post請求頭和數(shù)據(jù) header = { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "keep-alive", "Content-Length": "691", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Cookie": "EPORTAL_COOKIE_SERVER=; EPORTAL_COOKIE_DOMAIN=; EPORTAL_COOKIE_SAVEPASSWORD=true; EPORTAL_COOKIE_OPERATORPWD=; EPORTAL_COOKIE_USERNAME=SCXY15182972294; EPORTAL_COOKIE_NEWV=true; EPORTAL_COOKIE_SERVER_NAME=;", "Host": "XXXX", #根據(jù)自己的瀏覽器配置項配置 "Origin": "XXXXX", #根據(jù)自己的瀏覽器配置項配置 "Referer": "XXXXX", #根據(jù)自己的瀏覽器配置項配置 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36", } data = { "userId": 'XXXXX', #根據(jù)自己的瀏覽器配置項配置 "password": 'XXXXX', #根據(jù)自己的瀏覽器配置項配置 "queryString": 'XXXXX', #根據(jù)自己的瀏覽器配置項配置 "passwordEncrypt": 'true', "operatorPwd": '', "operatorUserId": '', "validcode": '', "service": '', } # 發(fā)送登錄請求 try: post_response = requests.post(post_URL, data=data, headers=header, timeout=15) print(f"POST請求狀態(tài)碼: {post_response.status_code}") get_response = requests.get(get_URL, timeout=15) print(f"GET請求狀態(tài)碼: {get_response.status_code}") except requests.exceptions.RequestException as e: print(f"請求異常: {e}") # 日志記錄(添加異常處理) try: with open(log_file_path, 'a', encoding='utf-8') as log_file: log_file.write( f"{time.strftime('%Y-%m-%d %H:%M:%S')} - 狀態(tài): {'已登錄' if title == '登錄成功' else '未登錄'}\n") if os.path.getsize(log_file_path) > 1024: log_file.seek(0) log_file.truncate() # 更安全的清空方式 except IOError as e: print(f"日志寫入失敗: {e}") # 隨機休眠(1小時±100秒) delay = 3600 + random.uniform(-100, 100) print(f"下次檢測將在 {int(delay)} 秒后...\n") time.sleep(delay)
使用方法
1.安裝依賴:確保已安裝requests和win10toast庫。可以通過以下命令安裝:
pip install requests #必須安裝 pip install requests win10toast #如果要使用Windows彈窗功能可以安裝(選擇性安裝)
2.運行腳本:直接運行Python腳本即可。腳本會自動檢測當前網(wǎng)絡狀態(tài),并根據(jù)需要進行登錄操作。
3.打包:
先安裝好pyinstall工具
pip install pyinstall
最后用pyinstall工具把.py文件打包成.exe可執(zhí)行文件
完整打包命令參考
pyinstaller --onefile --noconsole --hidden-import=win10toast --icon=my_icon.ico your_script.py
--onefile: 打包成單個 .exe 文件。
--noconsole: 禁止控制臺彈窗。
--hidden-import=win10toast: 顯式包含 win10toast 依賴(如果自動檢測失?。?br />--icon=my_icon.ico: 可選,為 .exe 添加自定義圖標。
打包后如下,在dist里面找到.exe可執(zhí)行程序,雙擊測試運行。
4.設置開機自啟動,完全解放雙手
鍵盤同時按住"win","R"鍵打開命令窗口,輸入以下命令:
將剛剛發(fā)送到的快捷方式拖入打開的文件夾中即可每次在開機時自動運行程序,無需手動啟動。
注意:建議將源文件夾放在一個不長修改的地方。
五、效果展示
日志文件
2024-03-01 09:00:00 - 狀態(tài): 已登錄
2024-03-01 10:05:23 - 狀態(tài): 未登錄
運行截圖
六、擴展方向(按需選擇)
1.多平臺支持
# 適配Linux通知 import notify2 notify2.init("Campus Network")
2.微信通知集成
# 通過Server醬發(fā)送提醒 requests.post("https://sc.ftqq.com/SCUKEY.send", data={"text": "網(wǎng)絡狀態(tài)提醒"})
3.可視化監(jiān)控面板
# 使用Flask搭建Web界面 pip install flask
七、注意事項
1.信息安全
不要明文存儲密碼
建議使用環(huán)境變量保存敏感信息
2.網(wǎng)絡合規(guī)
僅限個人設備使用
遵守校園網(wǎng)使用規(guī)定
3.異常處理
遇到持續(xù)認證失敗應停止嘗試
添加最大重試次數(shù)限制
九、總結
這個自動化腳本極大地簡化了校園網(wǎng)連接的過程,節(jié)省了學生的時間和精力。通過定期檢測和自動登錄,確保用戶始終能夠保持在線狀態(tài)。同時,日志記錄和錯誤處理機制也提高了腳本的可靠性和易用性。希望這個腳本能夠幫助更多的學生享受更加便捷的網(wǎng)絡體驗。
以上就是Python實現(xiàn)全自動校園網(wǎng)認證與登錄腳本的詳細內容,更多關于Python校園網(wǎng)認證登錄的資料請關注腳本之家其它相關文章!
相關文章
對python中的six.moves模塊的下載函數(shù)urlretrieve詳解
今天小編就為大家分享一篇對python中的six.moves模塊的下載函數(shù)urlretrieve詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12