目录
前言
咦惹,转眼间,悲惨的西电大学牲寒假就要结束了。博主突然想起还有五门期末考试没考,还要打数模美赛,心拔凉拔凉的,赶紧去吃个烤肉暖和暖和(手动狗头)。
言归正传,由于该死的疫情,回学校要提前14天在健康卡系统上连续打卡(不然返校就要写检讨...)。
想必XDer都苦受晨午晚检打卡折磨久矣,健康卡打卡原理与晨午晚检类似。在西电微信企业号内每天手动填报。在被导员无数次催打卡后萌生了用“科技手段”实现自动打卡的想法。
经过两天的摸索与两天的测试,终于实现了这个功能,使我免受打卡之苦,欣慰欣慰 !
本着知识贡献的理念我写下这个教程,希望能帮助各位同学。
免责声明:如果出现任何异常比如发烧等情况,请一定立刻马上上报!本文章不承担责任。出现签到失败或者其他情况,本文章不承担责任。
一、分析页面
手机打开健康卡系统,如下图
点右上角三个点,再复制链接,链接为https://xxcapp.xidian.edu.cn/ncov/wap/default/index
用 Microsoft Edge 浏览器打开,将自己的信息都填写好,然后按F12进入网页开发者工具。
如图所示,点击网络,标头。然后在左边提交刚才填写的信息。右边就出现我们需要的东西。
需要查看的内容:
POST请求URL (上传表单内容的地址)
User-Agent (用户代理)
再点击Payload 表单数据(即为我们要上传的数据)
这些后面会用到
二、获取cookies
1.引入库
代码如下:
from urllib import parse
import requests
import time
import json
2.获取cookies
如下代码只需将学号密码,User-Agent改为自己的
def getCookie(self):
url_login = "https://xxcapp.xidian.edu.cn/uc/wap/login/check" #西电一站式登陆地址(无需改动)
data_login = {
# 用户信息修改
"username": self.username, #你的学号
"password": self.password #你的密码
}
# Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome /77.0.3865.120 Safari/537.36
headers_login = {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ ×××"
#改成刚才查看到的
}
while True:
num = 1
try:
r = requests.post(url_login, data=data_login, headers=headers_login)
r.raise_for_status()
break
except:
time.sleep(1)
num += 1
finally:
if num > 5:
print("ALERT: TimeOutError...")
break
cookies_dict = requests.utils.dict_from_cookiejar(r.cookies)
# 使用utils.dict_from_cookiejar 将cookies数据类型转化为字典
self.cookies = parse.urlencode(cookies_dict).replace("&", ";")
三、上传数据
url_upload即为刚才查看的POST地址
data_upload即为刚才查看的表单数据,改为自己想要的即可。(具体含义请看代码注释)
def dataUpload(self):
url_upload = "https://xxcapp.xidian.edu.cn/ncov/wap/default/save"
data_upload = {
#家庭所在地地址
"area": self.area, #省份 地市 区
"province": self.province, #省份
"city": self.city, #地市
"sfcyglq": "0", # 是否隔离期
"sfyzz": "0", # 是否有症状
"qtqk": "", # 其他情况
"ymtys": "0", # 一码通颜色
"sfzx": "0", #是否在校
"zgfxdq": "0", #中高风险地区
"tw": "3", #体温
"sfcxtz": "0", #是否出现特征
"sfjcbh": "0", #是否接触病患
"mjry": "0", #密接人员
"csmjry": "0", #场所密接人员
"sfcyglq": "0", #是否处于隔离期
"sfjcjwry": "0", #是否接触境外人员
"sfcxzysx": "0" #是否出现注意事项
}
headers_upload = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/×××",
"cookie": self.cookies
}
try:
r = requests.post(url_upload, headers=headers_upload, data=data_upload)
r.raise_for_status()
except:
print("upload failed!")
exit(0)
response = json.loads(r.text)
print(response['m'] + " " + time.asctime(time.localtime(time.time())))
四、邮箱提醒模块
为了避免代码或者服务器运行出现问题,也为了方便调试。我引入了邮箱提醒功能,如果发现某天没有邮箱提醒,就意味着出现问题,需要调试。
1.引入库
import smtplib
from email.mime.text import MIMEText
from email.header import Header
2.邮箱发送
def emails(self):
# 发信方的信息:我用的是QQ邮箱,
from_addr = '×××××..@qq.com' #发信方的邮箱,
password = '××××..' #QQ 邮箱授权码,自行百度查询即可
# 收信方邮箱
to_addr = '×××××..@qq.com' #收信方的邮箱(打卡人的)
# 发信服务器
smtp_server = 'smtp.qq.com'
# 邮箱正文内容,第一个参数为内容,第二个参数为格式(plain 为纯文本),第三个参数为编码
msg = MIMEText('健康卡已打卡', 'plain', 'utf-8')
# 邮件头信息
msg['From'] = Header(from_addr)
msg['To'] = Header(to_addr)
msg['Subject'] = Header('健康卡')
# 开启发信服务,这里使用的是加密传输
server = smtplib.SMTP_SSL(smtp_server)
server.connect(smtp_server, 465)
# 登录发信邮箱
server.login(from_addr, password)
# 发送邮件
server.sendmail(from_addr, to_addr, msg.as_string())
# 关闭服务器
server.quit()
五、完整代码及其使用方法
为了使用方便,我把上述代码编写成类,可以一次帮多账号打卡
from urllib import parse
import urllib3
import requests
import time
import json
import smtplib
from email.mime.text import MIMEText
from email.header import Header
class Healthload:
def __init__(self, username1, password1, addr1, area1, province1, city1):
self.username = username1
self.password = password1
self.addr = addr1
self.area = area1
self.province = province1
self.city = city1
# 通过账号密码获取cookies
def getCookie(self):
url_login = "https://xxcapp.xidian.edu.cn/uc/wap/login/check"
data_login = {
"username": self.username,
"password": self.password
}
# Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome /77.0.3865.120 Safari/537.36
headers_login = {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/×××"
}
while True:
num = 1
try:
r = requests.post(url_login, data=data_login, headers=headers_login)
r.raise_for_status()
break
except:
time.sleep(1)
num += 1
finally:
if num > 5:
print("ALERT: TimeOutError...")
break
cookies_dict = requests.utils.dict_from_cookiejar(r.cookies)
# 使用utils.dict_from_cookiejar 将cookies数据类型转化为字典
self.cookies = parse.urlencode(cookies_dict).replace("&", ";")
# 将数据上传
def dataUpload(self):
url_upload = "https://xxcapp.xidian.edu.cn/ncov/wap/default/save"
data_upload = {
# 地址修改
"area": self.area,
"province": self.province,
"city": self.city,
"sfcyglq": "0", # 是否隔离期
"sfyzz": "0", # 是否有症状
"qtqk": "", # 其他情况
"ymtys": "0", # 一码通颜色
"sfzx": "0", #是否在校
"zgfxdq": "0", #中高风险地区
"tw": "3", #体温
"sfcxtz": "0", #是否出现特征
"sfjcbh": "0", #是否接触病患
"mjry": "0", #密接人员
"csmjry": "0", #场所密接人员
"sfcyglq": "0", #是否处于隔离期
"sfjcjwry": "0", #是否接触境外人员
"sfcxzysx": "0" #是否出现注意事项
}
headers_upload = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/×××",
"cookie": self.cookies
}
try:
r = requests.post(url_upload, headers=headers_upload, data=data_upload)
r.raise_for_status()
except:
print("upload failed!")
exit(0)
response = json.loads(r.text)
print(response['m'] + " " + time.asctime(time.localtime(time.time())))
def emails(self):
# 发信方的信息:发信邮箱,QQ 邮箱授权码
from_addr = '××××..@qq.com'
password = '××××..'
# 收信方邮箱
to_addr = self.addr
# 发信服务器
smtp_server = 'smtp.qq.com'
# 邮箱正文内容,第一个参数为内容,第二个参数为格式(plain 为纯文本),第三个参数为编码
msg = MIMEText('健康卡已打卡', 'plain', 'utf-8')
# 邮件头信息
msg['From'] = Header(from_addr)
msg['To'] = Header(to_addr)
msg['Subject'] = Header('健康卡')
# 开启发信服务,这里使用的是加密传输
server = smtplib.SMTP_SSL(smtp_server)
server.connect(smtp_server, 465)
# 登录发信邮箱
server.login(from_addr, password)
# 发送邮件
server.sendmail(from_addr, to_addr, msg.as_string())
# 关闭服务器
server.quit()
x1 = Healthload("你的学号", "密码", "打卡人的邮箱", " ××省 ××市 ××区", "××省", "××市")
x1.getCookie()
x1.dataUpload()
x1.emails()
x2= .. #同上,可以多创建几个对象(账号)一起打卡
使用方法:
getCookie方法中header_login中User-Agent改成自己的(dataUpload方法中也同样)
emails方法中 from_addr 、password改为自己的
然后创建对象,按照x1的格式,依次填好信息。
然后运行即可,此时查看手机是否成功打卡
有同学会问:咦,这样岂不是我每次打卡都得打开电脑运行程序,还不如用手机呢
接下来就需要把我们的代码放在服务器上运行,然后设置定时运行程序,就可以达到我们的目的。
六、服务器获取
服务器其实可以理解为一台在云端上的电脑,让它来帮我们运行程序。
对于我们这个程序,用一般的服务器就可以了。博主使用过百度的和华为的,个人更推荐华为的,觉得华为的更方便一些(原因是有现成的python,不用再另外安装)。这两家的新用户都可以白嫖一个月。我这里放上华为的链接特惠专区_云服务器_云主机_企业上云-华为云 (huaweicloud.com)
点开显示0元的就行,如下图,选择ubuntu系统,设置密码。然后购买就可以了。
然后进入控制台就可以查看、管理服务器
点击远程登录,再点CloudShell登陆,输入密码登陆
进入如下黑色界面
输入 python3 --version 回车
即可看到python版本(这就是为什么推荐华为的服务器,百度的要输入一堆指令安装python)
自此,服务器搞定
七、把程序放在服务器上运行
我们需要把程序放在服务器上才能运行。
这里有两种方法
1、方法一(普适方法,所有服务器都可以如此)
下载远程传输软件,这里推荐FileZilla,贼拉好用
网站放这里了 FileZilla中文网 - 免费开源的FTP解决方案 自行下载
下载完成后打开
主机输入你刚才获得的服务器的公网ip(上面那个),用户名root,密码是你刚才设置的,端口22
点击快速连接。右边显示即为连接成功。右边的就是服务器目录,左边是我们电脑目录。
在右边找到home文件夹
双击,新服务器home里应该是空的,然后在左边我们的电脑文件夹里找到我们刚才写好的python文件,双击即可传输到右边home里,这样就把需要运行的程序放在服务器上了
2.方法二(懒人方法,华为服务器)
此方法效果和第一种是一样的,相比之下简单多了,打开华为的黑色界面,就能看到服务器的文件目录。
直接点开home,右键创建python文件,把代码复制进去就行了。(呜呜华为的属实好用~)
八、设置定时运行
程序已经放在服务器上了,我们只需要每天定时运行一次即可。
这里博主踩了不少坑。跟着我的步骤走就可以了
在服务器命令行,输入crontab -e 回车进入编辑界面(会让你选择一个编辑器,初学者选择nano编辑器就可以了)
选择完编辑器后是这样的(这是我已经输入命令之后的界面,意思就是每天早上8点运行这个python程序,把日志写入log日志中,如果想设置其他时间的,自行修改即可)
0 8 * * * python3 /home/jiankangka.py > /home/jiankangka.log #输入这个
输入完成后 按ctrl+o,然后回车就保存好了,然后按ctrl+x,就退出了编辑界面
出现这个就意味着成功设置了
总结
自此,我们的整个过程就结束了。需要测试一下是否正常运行。就是到我们设置的时间,看有没有发邮箱通知或者打卡成功。如果没有,需要打开log日志看看哪里报错出现问题。再调试解决即可。
本教程比较详细,有基础的同学一到俩小时即可搞定。如果没有基础,按着教程一步步来,是个很好的实战,也能有意想不到的收获。
博主第一次写文,希望把过程交代清楚,避免同学们走弯路(博主当时踩了不少坑,欲哭无泪),语句繁琐请见谅。还望同学们多多点赞转发。写文不易,欢迎打赏
(如果有同学遇到问题或者嫌麻烦,可私信我解决哦~)