1 Star 0 Fork 0

海修 / campus_net

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
campus_net.py 9.16 KB
一键复制 编辑 原始数据 按行查看 历史
海修 提交于 2023-06-18 06:20 . !7添加功能以及修复bug
from pathlib import Path
from typing import Optional, Tuple
from time import sleep
import requests
import bs4
from tkinter import messagebox as box
import rtoml as toml
from utils import LoginResult, ResultTitle, detect_net
from ui.config_window import Win
total_retry = 1000 # 最多尝试1000次
SSID = "zut-stu"
is_block = False
# 读取账号信息
isps = {
"中国移动": "cmcc",
"中国联通": "unicom",
"中国电信": "telecom",
"校园单宽": "founder",
"校园内网": "free",
}
msg = {"username": "未输入学号", "password": "未输入密码", "isp": "未知运营商"}
def run(user_info) -> LoginResult:
global is_block
is_block = user_info["block"] if "block" in user_info else False
try:
username = user_info["username"]
password = user_info["password"]
my_isp = isps[user_info["isp"]]
except KeyError as e:
win = Win()
win.mainloop()
# loss_key = e.args[0]
# box.showerror(title="配置文件错误", message=msg[loss_key])
return LoginResult.fail
if username == "":
box.showerror(title="配置文件错误", message=msg["username"])
elif password == "":
box.showerror(title="配置文件错误", message=msg["password"])
# 断开wifi并连接"zut-stu"
auto_connect_wifi = (
user_info["auto_connect_wifi"] if "auto_connect_wifi" in user_info else False
)
if auto_connect_wifi:
# ping 1.1.1.1来查看是否连接上了校网服务器
is_connect = False
retry_times = 0
while not is_connect:
try:
_connect_wifi_pywifi()
except ImportError:
_connect_wifi_cmd()
except (EnvironmentError, ValueError):
raise
except:
is_connect = False
retry_times += 1
if retry_times <= total_retry:
return LoginResult.fail
else:
continue
sleep(1)
is_connect = detect_net()
# 读取配置并构建待发送的url
try:
url, data, headers = _build_data(username, password, my_isp)
except Exception as e:
if is_block:
box.showerror(title="网络错误", message=str(e))
return LoginResult.fail
else:
if _try_connect(url, headers, data, 2):
if is_block:
box.showinfo(title="登录成功", message="登录成功")
return LoginResult.success
else:
if is_block:
box.showerror(title="登录失败", message="登录失败")
return LoginResult.fail
def _try_connect(url, headers, data, re_try) -> bool:
"""
尝试连接校园网并通过ping baidu的方法来判断是否成功连接
Args:
url: 校园网连接用的访问网址
headers: 连接用的访问数据头
data: 连接用的访问具体数据
re_try: 重试次数
Returns: 如果能够连接,则返回True
如果不能连接,或者超出了重试次数则返回False
"""
if re_try <= 0:
return False
success = False
# 发送url并获取响应
response = requests.post(url=url, headers=headers, data=data)
# 处理响应
success = _process_response(response)
if success:
return True
else:
if detect_net("baidu.com", timeout=2):
return True
else:
return _try_connect(url, headers, data, re_try - 1)
def _connect_wifi_pywifi() -> None:
"""
尝试使用pywifi连接校园网
Returns:
"""
import pywifi
wifi = pywifi.PyWiFi()
interface = wifi.interfaces()[0]
interface.disconnect()
status = interface.status()
if status == pywifi.const.IFACE_DISCONNECTED:
profile = pywifi.Profile()
profile.ssid = SSID # type: ignore
conn_profile = interface.add_network_profile(profile)
interface.connect(conn_profile)
sleep(1.5)
status = interface.status()
if status != pywifi.const.IFACE_CONNECTED and is_block:
box.showerror(title="连接失败", message=f"请检查无线环境,查看是否存在{SSID=} wifi,并重新运行本程序")
else:
if is_block:
box.showwarning(title="状态异常", message="已连接有wifi,请断开如果不是zut-stu,则请断开。")
def _connect_wifi_cmd() -> None:
"""
尝试使用命令行工具来连接校园网
但是可能会需要使用平台自带的命令行工具,如果没有这个工具则会抛出无法解决的异常
Returns:
"""
import os
import subprocess as sp
OK_code = 0
# 判断系统平台
if os.name == "nt":
# windows平台
disconn_cmd = "netsh wlan disconnect"
conn_cmd = f"netsh wlan connect name={SSID} ssid={SSID}"
elif os.name == "posix":
if os.uname().sysname == "Darwin":
# macOS
cmd_out = sp.run("networksetup -listallhardwareports", shell=True,
capture_output=True, text=True)
if cmd_out.returncode != OK_code:
raise EnvironmentError("您没有安装networksetup工具")
default_network = ""
for l in cmd_out.stdout.split("\n"):
info = l.split()
if "Device" not in info[0]:
continue
default_network = info[1]
break
if default_network:
disconn_cmd = f"networksetup -setairportnetwork {default_network} \"\" \"\""
conn_cmd = f"networksetup -setairportnetwork {default_network} \"{SSID}\" \"\""
else:
raise EnvironmentError("未找到可用的网卡")
elif os.uname().sysname == "Linux":
# linux
disconn_cmd = f"nmcli dev wifi disconnect"
conn_cmd = f"nmcli dev wifi connect={SSID}"
else:
raise EnvironmentError("仅支持windows,linux以及macos平台")
else:
raise EnvironmentError("仅支持windows,linux以及macos平台")
cmd_out = sp.run(disconn_cmd, shell=True, capture_output=True, text=True)
if cmd_out.returncode != OK_code:
raise ValueError(f"命令执行出错: {cmd_out.stdout}")
cmd_out = sp.run(conn_cmd, shell=True, capture_output=True, text=True)
if cmd_out.returncode != OK_code:
raise ValueError(f"命令执行出错: {cmd_out.stdout}")
def _build_data(username, password, my_isp) -> Tuple[str, dict, dict]:
resp = requests.get("http://1.1.1.1")
resp_html = bs4.BeautifulSoup(resp.text, features="html.parser")
wlanuserip = resp_html.select("script")[2].text.split()[3].split("=")[2].strip("'")
url = (
"http://1.1.1.1:801/eportal/?c=ACSetting"
"&a=Login&protocol=http:"
"&hostname=1.1.1.1"
"&iTermType=1"
f"&wlanuserip={wlanuserip}"
"&wlanacip=10.10.9.200"
"&mac=00-00-00-00-00-00"
f"&ip={wlanuserip}"
"&enAdvert=0"
"&queryACIP=0"
"&loginMethod=1"
)
# 构建请求header
header = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,"
"application/signed-exchange;v=b3;q=0.9",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"Cache-Control": "max-age=0",
"Connection": "keep-alive",
"Content-Length": "162",
"Content-Type": "application/x-www-form-urlencoded",
"DNT": "1",
"Host": "1.1.1.1:801",
"Origin": "http://1.1.1.1",
"Referer": "http://1.1.1.1/",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 "
"Safari/537.36 Edg/106.0.1370.42",
}
# 构建请求body
body = {
"DDDDD": f",0,{username}@{my_isp}",
"upass": password,
"R1": "0",
"R2": "0",
"R3": "0",
"R6": "0",
"para": "00",
"0MKKey": "123456",
"buttonClicked": "",
"redirect_url": "",
"err_flag": "",
"username": "",
"password": "",
"user": "",
"cmd": "",
"Login": "",
}
return url, body, header
def _process_response(response: requests.Response) -> Optional[bool]:
response.encoding = "gbk"
resp_html = bs4.BeautifulSoup(response.text, features="html.parser")
if resp_html.title is None:
return False
title = resp_html.title.text
if title == ResultTitle.logined.value:
return False
elif title == ResultTitle.success.value:
return True
else:
return None
def main():
user_info = toml.load(Path(__file__).parent / "account.toml")
result = run(user_info)
print(result.value)
if user_info.get("schedule", False):
import schedule
schedule.run()
if __name__ == "__main__":
main()
Python
1
https://gitee.com/HaiXiu/campus_net.git
git@gitee.com:HaiXiu/campus_net.git
HaiXiu
campus_net
campus_net
requests

搜索帮助