python实现今日校园APP自动签到(二)

tech2022-12-18  159

python实现今日校园APP自动签到(二)

文章目录

python实现今日校园APP自动签到(二)序言一、签到过程与脚本设计思路签到过程设计思路流程图 二、抓包分析交互过程获取的签到表单submit提交签到表单 三、脚本代码的具体实现主程序dailyCP.pyWid更新程序update.py保活脚本keepAlive.py用户账号信息文件test.json表单任务ID文件Wid.json 四、云服务器部署创建存放目录shell脚本的部署主程序run.sh更新程序update.sh保活程序keepAlive.sh crontab计划任务的部署 总结


序言

上一期《python实现今日校园APP自动签到》发布之后,博主收到了小伙伴的私信,希望博主能协助这位小伙伴完成他学校的今日校园APP签到,一番交流后发现,不同的学校,签到的形式、具体用到的参数,相差甚远,原来的代码不能完完全全的直接复用,但编写的思路却是一样的,所以,本章节将给大家介绍一下某双一流大学今日校园APP自动签到的python编程。关于Charles抓包软件的设置和手机端网络代理设置的问题,可以参考上一期博文或其它资料,本文将不再赘述。

本文所有图片和代码,均已脱敏处理。


一、签到过程与脚本设计思路

签到过程

经过交流后得知,该校的签到是,一天签到三次,分早中晚三个时段。

早上 7:00~8:30 中午 12:00~13:30 晚上 22:00~23:00

三次签到,必须在这三个对应的时间段内;除此之外,还有定位限制,必须在要学校范围内,超出范围的无法签到

设计思路

有了签到的过程,那么我们就可以着手开始设计。每天3次签到,那么签到的主程序每天要执行3次,而且要在对应的时间段内执行; 考虑到3次签到的表单ID都不一样,所以表单ID的更新脚本,也要随之执行3次;最后则是保活脚本,为了让cookie能一直有效,需要不停的去访问任意页面,实现cookie的保活,这个每隔20分钟执行一次就好。

流程图


二、抓包分析交互过程

获取的签到表单

首先,分别打开早中晚三次签到的页面,看看charles抓包到的内容(图片已脱敏处理)

早晨签到的包: 中午签到的包: 晚上签到的包:

再对比多个早中晚的三个抓包,其实很容易发现的是,客户端每次都会向服务器请求两个参数:signInstanceWid和signWid 其中,signInstanceWid是表单ID,从早到晚,每次都不一样,且无规律递增; signWid则是对应早中晚三个任务的ID,这里称它为任务ID,每次都是固定这三个值: 早(466705) 中(466703) 晚(466708)

submit提交签到表单

submit提交签到的包:

从抓包中可以得知,传递的核心参数是signInstanceWid,也就是签到表的ID,其它的像longitude(经度)、latitude(维度)、position(定位地址)这些,说白了都是固定值,我人在校园内,那么这些值每次肯定都是一样的,可以直接写死。extraFieldItems是签到时额外弹出的框,要学生填写体温信息的,只要你体温正常不发烧,那么每次也都是这个数值(58679)。


三、脚本代码的具体实现

知悉了交互过程和传递的参数,那么就可以开始写脚本了

主程序dailyCP.py

#!/usr/bin/evn python #-*- coding:utf-8 -*- ''' ========================== =====POWER BY python3===== ======Author Task138====== ========================== ''' import requests, json, warnings, datetime warnings.filterwarnings('ignore') def getData(cookie, signInstanceWid): # 时段判断 # 当前时段 now_hour = datetime.datetime.now().hour # 签到时段 # 早:9 # 中:14 # 晚:23 sign_hour = 0 if now_hour < 9: sign_hour = 7 elif now_hour < 14: sign_hour = 12 else: sign_hour = 23 print(now_hour, sign_hour) if sign_hour == 7: signWid = '466705' elif sign_hour == 12: signWid = '466703' else: signWid = '466708' print(signInstanceWid, signWid) info = {} info['signInstanceWid'] = signInstanceWid headers = { 'Host': '这里填写抓包得到的学校域名', 'Content-Type': 'application/json', 'Cookie': cookie, 'Accept': '*/*', 'Accept-Language': 'zh-cn', 'Accept-Encoding': 'gzip, deflate, br', 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 (4833404928)cpdaily/8.2.1 wisedu/8.2.1', 'Connection': 'keep-alive', 'Origin': '这里填写抓包得到的学校域名' } url = '这里填写获取表单详情信息的URL' body = { 'signInstanceWid': signInstanceWid, 'signWid': signWid } data = json.dumps(body) req = requests.post(url=url, data=data, verify=False, headers=headers) thread = 200 for i in range(thread + 1): body = { 'signInstanceWid': str(int(signInstanceWid) + i), 'signWid': signWid } data = json.dumps(body) req = requests.post(url=url, data=data, verify=False, headers=headers) response = json.loads(req.text) now = datetime.datetime.today() current_date = now.strftime('%Y-%m-%d') try: senderUserName = response['datas']['senderUserName'] sign_date = response['datas']['rateSignDate'] rateTaskBeginTime = response['datas']['rateTaskBeginTime'] print(rateTaskBeginTime, body['signInstanceWid']) except: print(body) continue if ('这里填写辅导员的名字' in senderUserName) and (current_date in sign_date): if signWid == '466705': # 早上签到 if rateTaskBeginTime != '07:00': continue if signWid == '466703': # 中午签到 if rateTaskBeginTime != '12:00': continue if signWid == '466708': # 晚上签到 if rateTaskBeginTime != '22:00': continue new_signInstanceWid = response['datas']['signInstanceWid'] try: wid = response['datas']['extraField'][0]['extraFieldItems'][0]['wid'] except: wid = 58679 info['signInstanceWid'] = new_signInstanceWid info['wid'] = wid if new_signInstanceWid != signInstanceWid: with open('Wid.json', 'w') as fp3: new_data = '{"signInstanceWid":"%s"}' % (new_signInstanceWid) fp3.write(new_data) fp3.close() print('更新成功,当前数值:') print('signInstanceWid [ %s ]' % new_signInstanceWid) break else: print(senderUserName) return info def submitForm(cookie, info, username): headers = { 'Host': '这里填写抓包得到的学校域名', 'Content-Type': 'application/json', 'Cpdaily-Extension': '7Q881vmOiX7oHMgy2uiNNl8ZFV6TrEm+YxKkdJOzmMMGgT2eTPPHxBxY02LK 4Qq42SCAuunYl3r52lBcvtJAKSbT6h1n94BA3spnuAfnh7YCJbOJpAxjn9mx X8a8G9i9OYPNioL6UB76/x7ZeuZly9Ai1L6sAFWwtkczAcTdTSKdx+aqI5XO xPbqJrAztcBx+CtvFlsMsGcI2uKHLD3I2sgoFB4XoYhFv/4SjuWX+N/W24Oy oF8txhaTS1PJhmetIYLybnMWyAoiH6lmwknAMjSJdtqLe51u', 'Cookie': cookie, 'Accept': '*/*', 'Accept-Language': 'zh-cn', 'Accept-Encoding': 'gzip, deflate, br', 'User-Agent': '%E4%BB%8A%E6%97%A5%E6%A0%A1%E5%9B%AD/1 CFNetwork/1128.0.1 Darwin/19.6.0', 'Connection': 'keep-alive' } url = '这里填写post提交表单的URL' body = { "signInstanceWid": info['signInstanceWid'], "longitude": 这里填写抓包抓取到的经度, "latitude": 这里填写抓包抓取到的维度, "isMalposition": 0, "abnormalReason": "", "signPhotoUrl": "", "position": "这里填写定位的地址信息", "isNeedExtra": 1, "extraFieldItems": [{ "extraFieldItemValue": "小于37.3℃", "extraFieldItemWid": info['wid'] }] } data = json.dumps(body) req = requests.post(url=url, headers=headers, data=data, verify=False) response = req.text print(response) if "SUCCESS" in response: print('[ %s ]签到成功' % username) return True elif "该收集已填写无需再次填写" in response: print('[ %s ]签到成功' % username) return True elif "该收集已结束!" in response: print('[ %s ]签到成功' % username) return True elif "该签到已截止!" in response: print('[ %s ]签到成功' % username) return True else: print('[ %s ]签到失败' % username) return False if __name__ == '__main__': success = 0 failed = 0 failed_data = [] with open('test.json', 'r') as fp2: accounts = json.load(fp2) fp2.close() for k, v in accounts.items(): with open('Wid.json', 'r') as fp: data = json.load(fp) fp.close() signInstanceWid = data['signInstanceWid'] address = v['address'] cookie = v['cookie'] info = getData(cookie, signInstanceWid) submitForm(cookie, info, k)

Wid更新程序update.py

#!/usr/bin/env python #-*- coding:utf-8 -*- ''' ================================= ================================= =========Author:Task138========== ========Power By Python3========= ================================= ================================= ''' import requests, json, warnings, time, platform, datetime, threading, random with open('Wid.json', 'r') as fp: data = json.load(fp) fp.close() signInstanceWid = data['signInstanceWid'] warnings.filterwarnings('ignore') def getData(cookie, signInstanceWid): # 时段判断 # 当前时段 now_hour = datetime.datetime.now().hour # 签到时段 # 早:9 # 中:14 # 晚:23 sign_hour = 0 if now_hour < 9: sign_hour = 7 elif now_hour < 14: sign_hour = 12 else: sign_hour = 23 print(now_hour, sign_hour) if sign_hour == 7: signWid = '466705' elif sign_hour == 12: signWid = '466703' else: signWid = '466708' print(signInstanceWid, signWid) info = {} info['signInstanceWid'] = signInstanceWid headers = { 'Host': '这里填写抓包得到的学校域名', 'Content-Type': 'application/json', 'Cookie': cookie, 'Accept': '*/*', 'Accept-Language': 'zh-cn', 'Accept-Encoding': 'gzip, deflate, br', 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 (4833404928)cpdaily/8.2.1 wisedu/8.2.1', 'Connection': 'keep-alive', 'Origin': '这里填写抓包得到的学校域名' } url = '这里填写获取表单详情信息的URL' body = { 'signInstanceWid': str(int(signInstanceWid)+1), 'signWid': signWid } data = json.dumps(body) req = requests.post(url=url, data=data, verify=False, headers=headers) thread = 200 for i in range(thread + 1): body = { 'signInstanceWid': str(int(signInstanceWid) + i), 'signWid': signWid } data = json.dumps(body) req = requests.post(url=url, data=data, verify=False, headers=headers) response = json.loads(req.text) now = datetime.datetime.today() current_date = now.strftime('%Y-%m-%d') try: senderUserName = response['datas']['senderUserName'] sign_date = response['datas']['rateSignDate'] rateTaskBeginTime = response['datas']['rateTaskBeginTime'] print(rateTaskBeginTime, body['signInstanceWid']) except: print(body) continue if ('这里填写辅导员的名字' in senderUserName) and (current_date in sign_date): if signWid == '466705': # 早上签到 if rateTaskBeginTime != '07:00': continue if signWid == '466703': # 中午签到 if rateTaskBeginTime != '12:00': continue if signWid == '466708': # 晚上签到 if rateTaskBeginTime != '22:00': continue new_signInstanceWid = response['datas']['signInstanceWid'] try: wid = response['datas']['extraField'][0]['extraFieldItems'][0]['wid'] except: wid = 58679 info['signInstanceWid'] = new_signInstanceWid info['wid'] = wid if new_signInstanceWid != signInstanceWid: with open('Wid.json', 'w') as fp3: new_data = '{"signInstanceWid":"%s"}' % (new_signInstanceWid) fp3.write(new_data) fp3.close() print('更新成功,当前数值:') print('signInstanceWid [ %s ]' % new_signInstanceWid) break else: print(senderUserName) return info with open('test.json', 'r') as fp2: accounts = json.load(fp2) fp2.close() for k, v in accounts.items(): with open('Wid.json', 'r') as fp: data = json.load(fp) fp.close() cookie = v['cookie'] signInstanceWid = data['signInstanceWid'] getData(cookie, signInstanceWid)

保活脚本keepAlive.py

#!/usr/bin/env python #-*- coding:utf-8 -*- ''' ================================= ================================= =========Author:Task138========== ========Power By Python3========= ================================= ================================= ''' import json, requests, warnings warnings.filterwarnings('ignore') def keepAlive(cookie, signInstanceWid): headers = { 'Host': '这里填写抓包得到的学校域名', 'Content-Type': 'application/json', 'Cookie': cookie, 'Accept': '*/*', 'Accept-Language': 'zh-cn', 'Accept-Encoding': 'gzip, deflate, br', 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 (4833404928)cpdaily/8.2.1 wisedu/8.2.1', 'Connection': 'keep-alive', 'Origin': '这里填写抓包得到的学校域名' } url = '这里填写获取表单详情信息的URL' body = { 'signInstanceWid': signInstanceWid, "signWid":"466705" } data = json.dumps(body) req = requests.post(url=url, data=data, verify=False, headers=headers) response = json.loads(req.text) status = response['message'] print(status) return status if __name__ == '__main__': with open('test.json', 'r') as fp2: accounts = json.load(fp2) fp2.close() for k, v in accounts.items(): with open('Wid.json', 'r') as fp: data = json.load(fp) fp.close() signInstanceWid = data['signInstanceWid'] cookie = v['cookie'] status = keepAlive(cookie, signInstanceWid) if status == 'SUCCESS': print('[ %s ] 保活成功' % k) else: print('[ %s ] 保活失败' % k)

用户账号信息文件test.json

{ "用户姓名(必须用Unicode编码)": { "cookie": "抓包抓到的cookie", "address": "定位地址(必须用Unicode编码)" } }

表单任务ID文件Wid.json

{"signInstanceWid":"35176"}

四、云服务器部署

创建存放目录

mkdir -p /data/dailyCP

随后进入dailyCP,把上述py脚本和json配置文件,存放进里面

shell脚本的部署

主程序run.sh

#!/bin/bash current_date=$(date "+%Y_%m_%d") log_name="${current_date}.log" if [ ! -d "./log" ]; then mkdir ./log fi if [ ! -f "./log/$log_name" ]; then touch ./log/$log_name fi current_time=$(date "+%Y_%m_%d_%H_%M_%S") echo $current_time >> ./log/$log_name python3 /data/dailyCP/dailyCP.py >> ./log/$log_name echo -e >> ./log/$log_name echo "done"

更新程序update.sh

#!/bin/bash current_date=$(date "+%Y_%m_%d") log_name="${current_date}.log" if [ ! -d "./update_log" ]; then mkdir update_log fi if [ ! -f "./update_log/$log_name" ]; then touch ./update_log/$log_name fi current_time=$(date "+%Y_%m_%d_%H_%M_%S") echo $current_time >> ./update_log/$log_name python3 /data/dailyCP/updateWid.py >> ./update_log/$log_name echo -e >> ./update_log/$log_name echo "done"

保活程序keepAlive.sh

python3 /data/dailyCP/keepAlive.py

crontab计划任务的部署

# 今日校园签到 */20 * * * * cd /data/dailyCP && sh keepAlive.sh 30 7 * * * cd /data/dailyCP && sh run.sh 30 12 * * * cd /data/dailyCP && sh run.sh 30 22 * * * cd /data/dailyCP && sh run.sh 10 7 * * * cd /data/dailyCP && sh update.sh 10 12 * * * cd /data/dailyCP && sh update.sh 10 22 * * * cd /data/dailyCP && sh update.sh

总结

这次的脚本的编写难度,相比上一期明显容易了很多,很多参数都是表面上的动态变量,实际上都可视为静态量。

最后必须申明,本文仅用于python的技术学习与交流,切勿用于其它非法用途,如果你真有发烧等疑似症状,一定要及时上报自己的主管部门或者学校单位,《中华人民共和国传染病防治法》第八章法律责任第六十五条~第七十七条已明确规定,未依照本法的规定履行职责,或者隐瞒、谎报、缓报传染病疫情,亦或者其他违法行为的都有相应的处罚规定;构成犯罪的,依法追究刑事责任。

最新回复(0)