先贴个地址:http://139.9.218.7/dailyup/login (由于某些原因,该网站目前已停止使用,非常抱歉)
下面是本系统核心——填报代码的详细介绍,仅供大家学习使用
import requests
from bs4 import BeautifulSoup
import base64
from Crypto.Cipher import AES
import math
import random
import json
class NWU(object):
# 西北大学统一认证服务登陆地址
__login_page_url = "http://authserver.nwu.edu.cn/authserver/login"
# 上一次打卡数据获取,其实用不到
__lasttime_reportdata_url = "https://app.nwu.edu.cn/ncov/wap/open-report/index"
# 上报数据提交地址
__dailyup_page_url = "https://app.nwu.edu.cn/ncov/wap/open-report/save"
def __init__(self):
self.__session = requests.session()
def login(self, username, raw_password):
# 访问登录页面
response = self.__session.get(self.__login_page_url)
# 获取页面相关参数
ds = BeautifulSoup(response.text, "html5lib")
lt = ds.select('input[name="lt"]')[0].get('value')
dllt = ds.select('input[name="dllt"]')[0].get('value')
execution = ds.select('input[name="execution"]')[0].get('value')
_eventId = ds.select('input[name="_eventId"]')[0].get('value')
rmShown = ds.select('input[name="rmShown"]')[0].get('value')
# 获取盐值,self.__get_aes_salt为NWU的类函数,写在后面
pwdDefaultEncryptSalt = self.__get_aes_salt(response.text)
# 新建实例,self.AESCipher为NWU类里定义的类,写在后面
pc = self.AESCipher(pwdDefaultEncryptSalt) # 初始化密钥
password = pc.encrypt(raw_password) # 加密
# 构建登录数据
data = {
"_eventId": _eventId,
"dllt": dllt,
"execution": execution,
"lt": lt,
"password": password,
"rmShown": rmShown,
"username": username,
}
# 发送登录请求
response_login = self.__session.post(self.__login_page_url, data=data)
# 处理返回信息
if response_login is not None:
# 获取相关信息,self.__get_msg为NWU的类函数,写在后面
msg = self.__get_msg(response_login.text)
if msg == 1:
title_soup = BeautifulSoup(response_login.text, 'html5lib')
title = title_soup.find('title')
if (title is None) or title.text != '统一身份认证':
return False
else:
print("登录成功!")
return True
elif msg == -1:
print("登录失败!")
return False
elif msg == -2:
print("需要验证码!")
return False
return False
def dailyup(self):
# 禁用安全请求警告
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# 获取上一次打卡数据,其实不需要,我们自己构造数据
# lasttime_response = self.__session.get(self.__lasttime_reportdata_url, verify=False)
# lasttime_data = json.loads(lasttime_response.text)
# sfzx = lasttime_data['d']['info']['sfzx']
# tw = lasttime_data['d']['info']['tw']
# sfcyglq = lasttime_data['d']['info']['sfcyglq']
# sfyzz = lasttime_data['d']['info']['sfyzz']
# qtqk = lasttime_data['d']['info']['qtqk']
#
# city = lasttime_data['d']['setting']['city']
# 构造填报数据
data = {
"sfzx": 1, # 是否在校
"tw": 1, # 体温
"area": "陕西省 西安市 碑林区", # 地区
"city": "西安市", # 城市
"province": "陕西省",
"address": "陕西省西安市碑林区张家村街道含光路150号西北工业大学附属中学含光校区",
"geo_api_info": '{"type":"complete","position":{"Q":34.247495659723,"R":108.93127794053902,"lng":108.931278,"lat":34.247496},"location_type":"html5","message":"Get ipLocation failed.Get geolocation success.Convert Success.Get address success.","accuracy":200,"isConverted":true,"status":1,"addressComponent":{"citycode":"029","adcode":"610103","businessAreas":[{"name":"环城南路","id":"610103","location":{"Q":34.250901,"R":108.94798100000002,"lng":108.947981,"lat":34.250901}},{"name":"长安路","id":"610113","location":{"Q":34.225014,"R":108.94260099999997,"lng":108.942601,"lat":34.225014}},{"name":"甜水井","id":"610104","location":{"Q":34.255614,"R":108.92899899999997,"lng":108.928999,"lat":34.255614}}],"neighborhoodType":"","neighborhood":"","building":"","buildingType":"","street":"含光路","streetNumber":"150号","country":"中国","province":"陕西省","city":"西安市","district":"碑林区","township":"张家村街道"},"formattedAddress":"陕西省西安市碑林区张家村街道含光路150号西北工业大学附属中学含光校区","roads":[],"crosses":[],"pois":[],"info":"SUCCESS"}', # gps数据,抓包获得
"sfcyglq": 0, # 是否处于隔离期
"sfyzz": 0, # 是否有症状
"qtqk": "", # 其他情况
"ymtys": "",
}
# 发送打卡请求
response_dailyup = self.__session.get(self.__dailyup_page_url, data=data, verify=False)
# 处理返回结果
if response_dailyup is not None:
msg = json.loads(response_dailyup.text)
e = msg['e']
m = msg['m']
if e == 0:
print("填报成功")
return True
elif e == 1:
print(m)
return False
else:
print(msg)
return False
return False
@staticmethod
def __get_msg(html):
soup = BeautifulSoup(html, 'html5lib')
span = soup.select('span[id="msg"]')
if len(span) == 0:
return 1
msg = soup.select('span[id="msg"]')[0].text
if msg == "您提供的用户名或者密码有误":
return -1
elif msg == "无效的验证码":
return -2
elif msg == "请输入验证码":
return -2
def __get_aes_salt(self, string):
'''
:param string: 登陆界面源码
:return: 盐值
'''
t1 = string.split('pwdDefaultEncryptSalt = "')[1]
t2 = t1.split('"')[0]
return t2
class AESCipher():
def __init__(self, key):
self.key = key
self.iv = self.random_string(16).encode()
def __pad(self, text):
"""填充方式,加密内容必须为16字节的倍数,若不足则使用self.iv进行填充"""
text_length = len(text)
amount_to_pad = AES.block_size - (text_length % AES.block_size)
if amount_to_pad == 0:
amount_to_pad = AES.block_size
pad = chr(amount_to_pad)
return text + pad * amount_to_pad
def encrypt(self, text):
"""加密"""
raw = self.random_string(64) + text
raw = self.__pad(raw).encode()
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
return base64.b64encode(cipher.encrypt(raw))
@staticmethod
def random_string(length):
aes_chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
aes_chars_len = len(aes_chars)
retStr = ''
for i in range(0, length):
retStr += aes_chars[math.floor(random.random() * aes_chars_len)]
return retStr
if __name__ == '__main__':
nwu = NWU()
login_info = nwu.login("201711****", "W******") # 登陆成功返回True,失败返回False
dailyup = nwu.dailyup()
完整版代码下载地址:https://download.csdn.net/download/qq_20793145/13458322
推广一下我写的超星自动化程序(自动观看视频,自动答题,自动提交),欢迎查看详细介绍:超星自动化学习
如果觉得本文对你有帮助请点个赞支持我呦!(●’◡’●)