基于阿里云服务器的我在校园班委自动管理系统
本文仅用于学习用途,转载请注明出处
关键词
python、fiddler抓包、服务器、我在校园、HTTP
(福利推荐:阿里云、腾讯云、华为云服务器最新限时优惠活动,云服务器1核2G仅88元/年、2核4G仅698元/3年,点击这里立即抢购>>>)
0-引言
因学校要求,班委需提醒未完成打卡同学打卡,否则扣除德育分,影响德育成绩。所以为实现班委我在校园的自动化管理,尝试使用python编写一个爬虫程序挂靠在服务器运行,实现每天的自动提醒管理。
经前期搜索,互联网上的我在校园爬虫未涉及班委的自动化管理,且仅仅通过token或者JWSESSION实现登录,时效性不好且操作麻烦。例如github上面的我在校园自动签到程序,通过token值实现签到,但现已经停止维护,且token值登录已经被我在校园登录给禁止。csdn和博客园的部分文章仅仅涉及通过抓包获取JWSESSION实现登录签到,但是有效期不长。
1-总流程图
2.1-抓包解析过程
部分关键信息已经打码
打开fiddler和我在校园小程序,登录,抓取到登录信息如下
由其中发现,我在校园登录是通过url中的符号 ? 来实现传值的,由于登录的时候没有后面的openid等值,猜测传入账号和密码就可以实现登录。
经检验,猜测正确。
按照正常流程进入班级管理界面,依次进入日渐日报管理和班级签到管理,而后检查抓包信息
我在校园班级管理界面
日检日报界面
同理进入签到页面检查,发现出入的参数有一个id
经检查,在上一级页面的respond的中,发现了该天的id,图略
2.2-构建爬虫程序
代码有注释,变量均采用英文命名,可直接阅读
#!/usr/bin/env Python # coding=utf-8 import requests import json import time class auto_tips: def __init__(self, username, password): self.not_heat_names_list = [] self.not_sign_names_list = [] # 保留登录信息 self.session = requests.session() self.cookies = None # 登入界面的post信息 self.login_url = 'https://gw.wozaixiaoyuan.com/basicinfo/mobile/login/username' self.login_data = { 'username': username, 'password': password } self.login_headers = { 'Host': 'gw.wozaixiaoyuan.com', 'Connection': 'keep-alive', 'Content-Length': '2', 'Accept': 'application/json, text/plain, */*', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat', 'Content-Type': 'application/json;charset=UTF-8', 'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Dest': 'empty', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-us,en' } # 班级日检日报的信息 self.getHeatUsers_url = 'https://student.wozaixiaoyuan.com/heat/getHeatUsers.json' self.getHeatUsers_headers = { 'Host': 'student.wozaixiaoyuan.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat', 'content-type': 'application/x-www-form-urlencoded', 'Accept-Encoding': 'gzip, deflate, br' } self.getHeatUsers_data = {'seq': '1', 'date': str(time.strftime("%Y%m%d")), 'type': '0'} # 测试用的,后边程序会更改 # 校区签到的列表 self.getList_url = 'https://student.wozaixiaoyuan.com/gradeManage/sign/getList.json' self.getList_headers = { 'Host': 'student.wozaixiaoyuan.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat', 'content-type': 'application/x-www-form-urlencoded', 'Accept-Encoding': 'gzip, deflate, br' } self.getList_date = { 'keyword': '', 'page': '1' } # 校区签到的班级成员情况 self.getSignResult_url = 'https://student.wozaixiaoyuan.com/gradeManage/sign/getSignResult.json' self.getSignResult_headers = { 'Host': 'student.wozaixiaoyuan.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat', 'content-type': 'application/x-www-form-urlencoded', 'Accept-Encoding': 'gzip, deflate, br' } self.getSignResult_data = { 'id': '' } def login(self): # 登入账号 self.login_url = self.login_url + "?username=" + str(self.login_data['username']) + "&password=" + str( self.login_data['password']) # 通过 url 的 '?' 方法写入参数 # 更新url res = self.session.post(url=self.login_url, headers=self.login_headers, data='{}') try: if json.loads(res.text)['code'] == 0: self.session.cookies.set('JWSESSION', res.headers['JWSESSION']) # 更新JWSESSION值 print('{}t登录成功'.format(time.strftime("%H:%M:%S"))) else: print('{}t登录失败:{}'.format(time.strftime("%H:%M:%S"), json.loads(res.text)['message'])) # 输出登录错误的错误原因 except: print('{}t登录错误'.format(time.strftime("%H:%M:%S"))) def get_HeatUsers(self): try: res = self.session.post(url=self.getHeatUsers_url, headers=self.getHeatUsers_headers, data=self.getHeatUsers_data) if json.loads(res.text)['code'] == 0: # 检查是否请求成功且正确 # print('{}t成功获得班级成员日检日报信息'.format(time.strftime("%H:%M:%S"))) data = json.loads(res.text)['data'] # 观察是否有不晨检的同学 if len(data) != 0: for inf in data: # 如果有,则更新不晨检列表 name = inf['name'] self.not_heat_names_list.append(name) print('{}t未完成日检日报的班级成员为{}'.format(time.strftime("%H:%M:%S"), self.not_heat_names_list)) else: print('{}t班级成员全部完成日检日报'.format(time.strftime("%H:%M:%S"))) else: print('{}t获得班级成员日检日报信息失败:{}'.format(time.strftime("%H:%M:%S"), json.loads(res.text)['message'])) # 输出登录错误的错误原因 except: print('{}t获得班级成员日检日报信息失败'.format(time.strftime("%H:%M:%S"))) def get_SignResult(self): # 获取当天的签到 id 值 try: res = self.session.post(url=self.getList_url, headers=self.getList_headers, data=self.getList_date) if json.loads(res.text)['data'][0]['end'].split(' ')[0] == time.strftime("%Y-%m-%d"): # 判断第一个签到是不是当天的签到 self.getSignResult_data['id'] = json.loads(res.text)['data'][0]['id'] # 如果判断成功,则更新 查询签到的id res = self.session.post(url=self.getSignResult_url, headers=self.getSignResult_headers, # 查询签到 data=self.getSignResult_data) data = json.loads(res.text)['data'] if len(data['notSign']) != 0: # 判断是否有成员不签到 for inf in data['notSign']: name = inf['name'] self.not_sign_names_list.append(name) print('{}t未完成签到的班级成员为{}'.format(time.strftime("%H:%M:%S"), self.not_sign_names_list)) else: print('{}t班级成员全部完成签到'.format(time.strftime("%H:%M:%S"))) except: print('{}t获得班级成员签到信息失败'.format(time.strftime("%H:%M:%S"))) if __name__ == '__main__': obj = auto_tips('账号名', '密码') obj.login() obj.get_HeatUsers() obj.get_SignResult()
2.3-构建邮件提醒程序
同上,可直接阅读
import smtplib from email.mime.text import MIMEText # email 用于构建邮件内容 from email.header import Header class email_obj: def __init__(self, to_addr=None, email_Subject=None, email_content=None): data_inf_path = r'系统日志email_data.txt' # 邮箱信息的存储路径 with open(data_inf_path, 'r+', encoding='UTF-8') as f: data_inf = eval(f.read()) # 读取邮箱信息 f.close() self.from_addr = data_inf['发信邮箱'] # 发信邮箱 self.password = data_inf['邮箱授权码'] # 发信邮箱的授权码 self.smtp_server = data_inf['发信服务器'] # 发信服务器的域名 self.to_addr = to_addr # 收信邮箱 self.email_Subject = email_Subject # 邮件标题 self.email_content = email_content # 邮件内容 # 开启发信服务,这里使用的是加密传输 self.server = smtplib.SMTP_SSL(host=self.smtp_server) # POP3/SMTP 协议的发送邮件服务器 self.server.connect(self.smtp_server, 465) # 使用SSL,端口号465 # 登录发信邮箱 self.server.login(self.from_addr, self.password) def change_email_inf_to(self, to_addr, email_Subject, email_content): self.to_addr = to_addr # 收信邮箱 self.email_Subject = email_Subject # 邮件标题 self.email_content = email_content # 邮件内容 def send(self): # 邮箱正文内容,第一个参数为内容,第二个参数为格式(plain 为纯文本),第三个参数为编码 msg = MIMEText(self.email_content, 'plain', 'utf-8') # 邮件头信息 msg['From'] = Header(self.from_addr) msg['To'] = Header(self.to_addr) msg['Subject'] = Header(self.email_Subject) # 发送邮件 self.server.sendmail(self.from_addr, self.to_addr, msg.as_string()) def close(self): # 关闭服务器 self.server.quit() if __name__ == '__main__': to_addr = [email protected]' email_Subject = 'send by python' email_content = 'python test' obj = email_obj(to_addr, email_Subject, email_content) obj.send()
定时触发程序
#!/usr/bin/env Python # coding=utf-8 import tips import send_email import pandas as pd import time def heat_tip(file): # 晨检提醒 obj = tips.auto_tips('真实账号', '真实密码') obj.login() obj.get_HeatUsers() name_list = obj.not_heat_names_list if len(name_list) != 0: user_email = send_email.email_obj() # 登录邮箱 for i in range(len(name_list)): # 依次编辑文件 name_i = name_list[i] for j in range(len(file)): name_j = file.iloc[j, 0] if name_i == name_j: qq = file.iloc[j, 1] qq_email = qq + [email protected]' email_Subject = '日检日报提醒' email_content = '赶紧晨检了,现在已经是{}了'.format(time.strftime("%H:%M:%S")) user_email.change_email_inf_to(to_addr=qq_email, email_Subject=email_Subject, email_content=email_content) user_email.send() user_email.close() # 退出邮箱 def sign_tip(file): # 签到提醒 obj = tips.auto_tips('真实账号', '真实密码') obj.login() obj.get_HeatUsers() name_list = obj.not_heat_names_list if len(name_list) != 0: user_email = send_email.email_obj() # 登录邮箱 for i in range(len(name_list)): # 依次编辑文件 name_i = name_list[i] for j in range(len(file)): name_j = file.iloc[j, 0] if name_i == name_j: qq = file.iloc[j, 1] qq_email = qq + [email protected]' email_Subject = '签到提醒' email_content = '赶紧晨检了,现在已经是{}了'.format(time.strftime("%H:%M:%S")) user_email.change_email_inf_to(to_addr=qq_email, email_Subject=email_Subject, email_content=email_content) user_email.send() user_email.close() # 退出邮箱 def seconds(now_time): # 把时间转化为秒 hour = int(now_time.split(':')[0]) minute = int(now_time.split(':')[1]) second = int(now_time.split(':')[2]) now_seconds = hour * 60 * 60 + minute * 60 + second return now_seconds def get_sleep_time(now_time, to_time): # 获得程序睡眠时间 sleep_time = seconds(to_time) - seconds(now_time) return sleep_time # 单位是s def auto_tips(): file = pd.read_excel(r'用户信息班级成员信息.xlsx') print('开始运行') # 晨检提醒时间 heat_tip_time_1 = '11:00:00' heat_tip_time_2 = '11:30:00' heat_tip_time_3 = '11:50:00' # 签到提醒时间 sign_tip_time_1 = '22:05:00' sign_tip_time_2 = '22:15:00' sign_tip_time_3 = '22:25:00' tips_time_list = [heat_tip_time_1, heat_tip_time_2, heat_tip_time_3, sign_tip_time_1, sign_tip_time_2, sign_tip_time_3] # 按顺序放好 #### while True: flag = 0 # 判断当前时间是否在提醒时间前 tip_name = None # 提醒的事件名称 sleep_time = None # 睡眠时间 for i in range(len(tips_time_list)): # 判断当前时间 tip_time = tips_time_list[i] now_time = time.strftime("%H:%M:%S") # 时:分:秒 if seconds(now_time) < seconds(tip_time): sleep_time = get_sleep_time(now_time=now_time, to_time=tip_time) if i <= 2: tip_name = '晨检' else: tip_name = '签到' flag = 1 break if flag == 0: now_time = time.strftime("%H:%M:%S") # 时:分:秒 sleep_time = get_sleep_time(now_time=now_time, to_time='24:00:00') + get_sleep_time(now_time='00:00:00', to_time=tips_time_list[0]) tip_name = '晨检' print('{}t即将休眠{}秒'.format(time.strftime("%H:%M:%S"), sleep_time)) time.sleep(sleep_time) if tip_name == '晨检': heat_tip(file) elif tip_name == '签到': sign_tip(file) print('{}t提醒信息已经发送'.format(time.strftime("%H:%M:%S"))) if __name__ == '__main__': # print(seconds('07:10:12')) auto_tips()
2.4-配置文件
文件如图配置
2.5-打包并且配置到服务器上
利用pyinstaller打包auto_tips.py
然后用命令控制符的mstsc命令,连接远程服务器,把整个文件夹上传到服务器运行。
3-过程碰到的问题
3.1-抓取不到登录界面
问题描述打开微信小程序,进入我在校园后,只获得了get信息,然后就自动转接微信授权登录,无法抓取到post信息
解决方法换另一台电脑登录后,再重新返回本电脑登录我在校园,微信授权登录就会失败,然后就可以账号密码登入,抓取到对应的信息
3.2-获取不了邮箱的授权码
问题描述我用的是阿里云购买的域名,解析到腾讯企业邮箱的服务器上,注册了域名邮箱。找不到对应的授权码
解决方法打开腾讯企业邮箱,给对应的邮箱开头SMTP服务,然后进入邮箱,设置中处理就可以了。详细教程网上可以查到
3.3nssm-把exe文件注册成服务
问题描述把exe文件通过nssm程序注册成计算机服务,后台运行服务时候,运行失败
暂未解决
你还在原价购买阿里云、腾讯云、华为云、天翼云产品?那就亏大啦!现在申请成为四大品牌云厂商VIP用户,可以3折优惠价购买云服务器等云产品,并且可享四大云服务商产品终身VIP优惠价,还等什么?赶紧点击下面对应链接免费申请VIP客户吧:
相关文章
- Linux 6.3 将进一步改进可重启序列(RSEQ),以提升运算性能
- 关联数据赋能智能化业务
- 解锁暗数据潜在业务价值的关键方法
- 基于OpenHarmony的智联北斗海防系统
- Zadig 面向开发者的自测联调子环境技术方案详解
- 深入理解 Linux 物理内存分配全链路实现
- 尘埃落定!IE永别,Edge接棒
- 你需要知道的ES6—ES13开发技巧!
- Harmonoid:基本够用的漂亮的跨平台音乐播放器
- 这三个 Go 水平自测题,手写不出来还是先老实上班吧
- 如何修复 Windows Update 更新错误 0x8024a205
- 技术管理如何应对混合工作模式转变
- 我来教你如何组装一个注册中心?
- 基于Java UI开发的小游戏—推箱子(上)
- 为什么 ThreadLocal 可以做到线程隔离?
- 什么是数据沿袭?相关技术、最佳做法和工具
- 一文读懂“语言模型”
- 大数据如何成为元宇宙的基石
- 比GDB更方便的代码调试工具:CGDB
- 如何启用大数据优秀实践