西北大学晨午检自助填报系统

先贴个地址: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

推广一下我写的超星自动化程序(自动观看视频,自动答题,自动提交),欢迎查看详细介绍:超星自动化学习

如果觉得本文对你有帮助请点个赞支持我呦!(●’◡’●)

你可能感兴趣的:(笔记)