├── .gitignore
├── requirements.txt
├── 打卡.xml
├── assets
├── image.png
├── img.png
├── 20210823_152151_image.png
├── 20210823_152753_image.png
├── 20210823_153454_image.png
├── 20210823_153558_image.png
├── 20210823_153633_image.png
├── 20210823_153733_image.png
├── 20210823_153947_image.png
├── 20210823_154344_image.png
├── 20210823_154708_image.png
├── 20210823_155142_image.png
├── 20210823_155336_image.png
├── 20210823_155531_image.png
├── 20210823_155602_image.png
├── 20210823_155941_image.png
├── 20210823_160006_image.png
├── 20210823_160011_image.png
└── 20210823_160040_image.png
├── .idea
├── vcs.xml
├── .gitignore
├── inspectionProfiles
│ └── profiles_settings.xml
├── modules.xml
├── misc.xml
├── zzu_jksb.iml
├── markdown-navigator.xml
└── markdown-navigator-enh.xml
├── LICENSE
├── README.md
└── zzu_jksb.py
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea/
2 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | requests==2.25.1
2 | beautifulsoup4==4.9.3
3 |
--------------------------------------------------------------------------------
/打卡.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/打卡.xml
--------------------------------------------------------------------------------
/assets/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/image.png
--------------------------------------------------------------------------------
/assets/img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/img.png
--------------------------------------------------------------------------------
/assets/20210823_152151_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_152151_image.png
--------------------------------------------------------------------------------
/assets/20210823_152753_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_152753_image.png
--------------------------------------------------------------------------------
/assets/20210823_153454_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_153454_image.png
--------------------------------------------------------------------------------
/assets/20210823_153558_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_153558_image.png
--------------------------------------------------------------------------------
/assets/20210823_153633_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_153633_image.png
--------------------------------------------------------------------------------
/assets/20210823_153733_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_153733_image.png
--------------------------------------------------------------------------------
/assets/20210823_153947_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_153947_image.png
--------------------------------------------------------------------------------
/assets/20210823_154344_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_154344_image.png
--------------------------------------------------------------------------------
/assets/20210823_154708_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_154708_image.png
--------------------------------------------------------------------------------
/assets/20210823_155142_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_155142_image.png
--------------------------------------------------------------------------------
/assets/20210823_155336_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_155336_image.png
--------------------------------------------------------------------------------
/assets/20210823_155531_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_155531_image.png
--------------------------------------------------------------------------------
/assets/20210823_155602_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_155602_image.png
--------------------------------------------------------------------------------
/assets/20210823_155941_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_155941_image.png
--------------------------------------------------------------------------------
/assets/20210823_160006_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_160006_image.png
--------------------------------------------------------------------------------
/assets/20210823_160011_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_160011_image.png
--------------------------------------------------------------------------------
/assets/20210823_160040_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoderXshuai/zzu_jksb/HEAD/assets/20210823_160040_image.png
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/zzu_jksb.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 CoderXshuai
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #为了响应学校疫情防控办的号召,请各位同学自觉遵守健康打卡规定,不要耍小聪明
2 | [郑州大学新型肺炎防控专题网站](http://www5.zzu.edu.cn/yqfk/)
3 | ## 2022-5-10
4 | 学校加了8.您是否按要求参加了核酸检测,已经修复,推测是`"myvs_9": "y"`
5 | ## 2022-5-9
6 | 学校加了8.您是否按要求参加了核酸检测,这个目前格式还不确定,根据经验推测是`myvs_8`,有需要可自行修改测试
7 | ## 2022-4-18
8 | 修复了refer异常,以后作设备校验可以参考用refer、host等,代码素养又得到了提高呢
9 | 但是`data`中有个`fun18`属性,这个属性暂时不知道是干嘛的,但参数经常变,合理怀疑是类似于
10 | 郑州大学通行码一样,每天变一下数字,方便后台/保安做检验的。
11 |
12 | **所以应该还不是很稳定**
13 | ## 2022-4-11
14 | ~~这个脚本暂时没法用,使用时会显示,个人猜测是加了参数校验~~
15 | # 郑州大学健康打卡自动脚本(Python)
16 |
17 | **现在学校开始识别IP地址了,
18 | 虽然我感觉早就应该识别了,如果服务器所在地和自己不在一个市的,
19 | 就不能挂在服务器上了,可以考虑挂在自己家的路由器(性能需要好一点的,K2P永远的神)上,
20 | 树莓派不知道可不可以,或者自己电脑每天开着机。**
21 |
22 | **下面会有如何用普通的win10电脑设置定时任务的教程,有需要可以自行查阅。** 并且导出了设置的脚本,可以直接导入自己的计算机中,修改程序位置即可。
23 |
24 | 打卡系统识别的IP有的时候是不准确的,在使用数据打卡的时候,有时候只会显示到某个省,市是识别不出来的(移动这样情况比较多),具体可以自己在浏览器输入"IP"
25 | 查一下,看看自己的IP能识别到哪个级别,如果是这种情况的话,默认会认为在省会,所以如果所在省的省会有公有的云服务器资源的话,还是可以的,问就是家里没有WIFI(WIFI就别想了,识别的很准确,基本上能到县级,但学校只获取到市级)
26 |
27 | ## 0.前言
28 |
29 | 对于大多数人来说每天的健康打卡几乎没有什么变化,我就想试试能不能做到自动打卡,就算是练手 Python以及云服务器.所以这个脚本仅供学习交流,下面我会列出**学习**此脚本所涉及的基础知识.
30 |
31 | - Python,包括基础语法(列表,字典,函数,正则表达式)以及requests(模拟登录)
32 | ,BeautifulSoup(HTML解析)库的知识
33 | - 计算机网络,了解基础的Chrome浏览器调试工具以及发送请求的数据格式等
34 | - ~~云服务器,能在云服务器上运行Python代码并能设置定时任务(不了解的可以看一下我写的一篇博客
35 | [玩转服务器](https://editor.csdn.net/md/?articleId=107212739) )~~
36 |
37 | 如果只是浅层学习的话,会云服务和Python就可以 如果有学到,请给个star
38 |
39 | ## 1.浅层学习说明
40 |
41 | 把zzu_jssk.py文件下载到本地之后, 安装requests(模拟登录),BeautifulSoup(HTML解析)库, 并更改user和data数据变成你自己的数据
42 | 
43 | user和data均为字典,user是你的登录名和密码, data是最后填报的数据,每一项数据代表的含义都注释了,和填报的顺序完全一致
44 |
45 | 
46 | 可自行对比查看
47 |
48 | 别的数据无特别情况无需变动 之后把代码上传到~~云服务器上~~ 自己电脑上,设置一个定时任务, 然后就可以自动的帮你打卡了.
49 |
50 | ## 1.1 win10设置定时任务教程
51 |
52 | - 在win10右下角搜索**计算机管理**
53 |
54 | 
55 |
56 | - 选择**任务管理程序**->**任务管理程序库**->**Microsoft**->**Windows**,并单击**Windows**
57 |
58 | 
59 | - 右键选择**创建基本任务**,或者在右边栏找到**创建基本任务**
60 |
61 | 
62 | - **名称**和**描述**可以随意,这里以下图的名称和描述为例,点击下一步
63 |
64 | 
65 | - 频率选择**每天,下一步
66 |
67 | 
68 | - 开始时间选择一个,你们辅导员催你打卡的时间之前,👀️ 。这里以0:05为例,点击下一步
69 |
70 | 
71 | - 选择启动程序(其实也没得选,因为别的都弃用了,可以自己实现一个),选择下一步
72 |
73 | 
74 | - 重点来了,这里的**程序或脚本**选择你本地的python.exe文件的路径,如果不知道,可以去环境变量里查,如果还不知道,用everything之类的工具搜索一下python.exe吧。添加参数选择打卡的.py文件。这里的意思相当于是,你在cmd中输入 E:\Python37\python.exe E:\PythonProject\zzu_jksb.py。是真正的启动脚本。点击下一步
75 |
76 | 
77 | - 至此,检查一下,看有没有问题,触发器就是启动时间和频率,操作就是执行脚本。没有问题就完成即可。图中的画框部分建议勾上,然后对属性进行设置。当然不勾也行,后面也有办法打开属性设置对话框。
78 |
79 | 
80 | - 剩下的步骤其实设置与否并不重要,但为了更稳定,建议设置上。具体如图
81 |
82 | 
83 |
84 | 
85 |
86 |
87 | 
88 |
89 | ## 2.深入学习说明
90 |
91 | 总体的实现思路就是通过Chrome的调试工具获取登录所需要的信息以及信息格式 之后用Python的requests库实现模拟登录,最后把代码放在云服务器上,设置好定时任务即可 技术要点
92 |
93 | - 通过调试工具获取到数据表单提交时候的表头和数据
94 | - 通过requests库对表头和数据安装格式组装,并模拟登录,需要注意的是把所有的返回的 response设置编码格式为utf-8,不然会出现乱码,影响后续
95 | - 用户登录之后会有一个超链接跳转到**选择填报人和填报类型**界面,因此需要 获取到这个超链接,把response返回的数据转换成文本格式就是返回的含有超链接的HTML代码, 然后使用正则表达式获取到此超链接
96 | - 选择填报人和填报类型界面的模拟登录思路和第一个一致,但需要获取到登录的session信息 供学校服务器验证,通过BeautifulSoup库的HTML解析功能获取到session信息
97 | ,并存入到info这个字典中供后续使用,但不需要额外获取超链接,提交之后 就是**填写上报表格**页面
98 | - **填写上报表格**页面需要获取用户需要提交数据(data)以及session验证信息组装之后 ,提交到服务器
99 | - 最后一步就是上传到云服务器,先购买一个云服务器,选择操作系统,以centos7为例需要安装 Python3,并更改自带的Python2的参数.之后安装宝塔面板作为可视化的后台界面 ,接着设置定时任务,执行脚本.
100 |
101 | ## 3.项目初衷
102 |
103 | 只是为了练手Python和云服务器,顺手做了这样一个项目,仅供学习. 之所以没有采用在Python代码中设置定时任务,因为打卡每天只要一次,如果在Python中
104 | 设置了定时任务,那么Python的代码需要一直运行,别说是自己电脑了,就是服务器这么做也太浪费资源了.直接在操作系统级别设置定时任务不香嘛?
105 |
106 | ## 4.项目改进
107 |
108 | 考虑到有的同学需要截图,如果后续有需要,可以打完卡之后自动获取到打卡成功的界面. 另外这个项目会持续跟进的,如果学校有了变动,会尽快升级的,毕竟我自己也要学习. 最后转载请标明出处,禁止牟利,低调学习使用哈.
109 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator-enh.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/zzu_jksb.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import my_re
3 |
4 | import requests
5 | from bs4 import BeautifulSoup
6 |
7 | user = {"no": "2019xxx", "password": "xxx"} # 学号 # 密码
8 |
9 | data = {
10 | "myvs_1": "否", # 1是否有发热 是/否
11 | "myvs_2": "否", # 2是否有咳嗽 是/否
12 | "myvs_3": "否", # 3是否有乏力症状 是/否
13 | "myvs_4": "否", # 4是否有鼻塞 是/否
14 | "myvs_5": "否", # 5是否被确诊 是/否
15 | "myvs_6": "否", # 6是否是疑似 是/否
16 | "myvs_7": "否", # 7是否是密切接触者 是/否
17 | "myvs_8": "否", # 8是否在医疗机构隔离 是/否
18 | "myvs_9": "y", # 9您是否按要求参加了核酸检测 y表示参加了
19 | "myvs_10": "否", # 10是否在居家隔离 是/否
20 | "myvs_11": "否", # 11小区/村是否有确诊 是/否
21 | "myvs_12": "否", # 12是否有共同具状人确诊 是/否
22 | "myvs_13a": "41", # 13a 所在省的身份证区划代码(前两位)如河南省=41
23 | "myvs_13b": "4101", # 13b所在省的身份证区划代码(前四位)如河南郑州=4101
24 | "myvs_13c": "河南省郑州市高新区科学大道100号", # 13c具体所在地
25 | "myvs_24": "否", # 是否为当日返郑人员
26 | "myvs_26": "5", # 应该是和疫苗有关,5是三针
27 | "memo22": "郑州大学主校区", # 目测是根据自己的校区修改
28 | # 以下内容无需更改
29 | "did": "2",
30 | "door": "",
31 | "day6": "b",
32 | "men6": "a",
33 | "sheng6": "",
34 | "shi6": "",
35 | "fun18": "381",
36 | "fun3": "",
37 | "jingdu": "113.535807", # 主校区经度
38 | "weidu": "34.81732", # 主校区纬度
39 | "ptopid": "",
40 | "sid": "",
41 | }
42 | # 以下内容无需改动
43 | user_agent = "Mozilla/5.0 (Linux; U; Android 2.3.6; zh-cn; GT-S5660 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MicroMessenger/4.5.255"
44 | host = "jksb.v.zzu.edu.cn"
45 | origin = "https://jksb.v.zzu.edu.cn"
46 | session = requests.session()
47 | info = {}
48 |
49 |
50 | # 登录函数
51 | def login(account, password):
52 | header = {
53 | "Origin": origin,
54 | "Referer": "https://jksb.v.zzu.edu.cn/vls6sss/zzujksb.dll/first0",
55 | "User-Agent": user_agent,
56 | "Host": host,
57 | }
58 | post_url = "https://jksb.v.zzu.edu.cn/vls6sss/zzujksb.dll/login"
59 | post_data = {
60 | "uid": account,
61 | "upw": password,
62 | "smbtn": "进入健康状况上报平台",
63 | "hh28": "722",
64 | }
65 | response = session.post(post_url, data=post_data, headers=header)
66 | response.encoding = "utf-8"
67 | return response.text
68 |
69 |
70 | # 选择填报人和填报类型
71 | def enter(html):
72 | url = get_url(html)
73 | response = session.get(url)
74 | response.encoding = "utf-8"
75 | new_html = response.text
76 | post_url = "https://jksb.v.zzu.edu.cn/vls6sss/zzujksb.dll/jksb"
77 | refer = url + "&fun2="
78 | header = {
79 | "Origin": origin,
80 | "Referer": refer,
81 | "User-Agent": user_agent,
82 | "Host": host,
83 | }
84 | post_data = get_session_data(new_html)
85 | # print(info)
86 | response = session.post(post_url, data=post_data, headers=header)
87 | response.encoding = "utf-8"
88 | return response.text
89 |
90 |
91 | # 获取选择填报人和填报类型界面的超链接
92 | def get_url(html):
93 | p = re.compile(r'parent.window.location="(.*?)"')
94 | s = str(p.findall(html)[0]).replace("first6", "jksb")
95 | return s
96 |
97 |
98 | # 获取登录的session信息
99 | def get_session_data(html):
100 | keys = ["did", "door", "men6", "ptopid", "sid"]
101 | values = []
102 | soup = BeautifulSoup(html, "html.parser")
103 | for key in keys:
104 | values.append(soup.find("input", {"name": key})["value"])
105 | global info
106 | info = dict(zip(keys, values))
107 | return info
108 |
109 |
110 | # 填写上报表格
111 | def submit(data):
112 | url = "https://jksb.v.zzu.edu.cn/vls6sss/zzujksb.dll/jksb"
113 | refer = 'https://jksb.v.zzu.edu.cn/vls6sss/zzujksb.dll/jksb?' + data['ptopid'] + '&' + data['sid'] + '&fun2'
114 | headers = {
115 | "User-Agent": user_agent,
116 | "Host": host,
117 | "Origin": origin,
118 | "Referer": refer
119 | }
120 | data["ptopid"] = info.get("ptopid")
121 | data["sid"] = info.get("sid")
122 | r = requests.post(url, headers=headers, data=data)
123 | r.encoding = "utf-8"
124 | str = r.text
125 | if str.find("感谢你今日上报健康状况") == -1:
126 | print(str)
127 | print("填报失败")
128 | else:
129 | print(return_message(str))
130 | print("填报成功!")
131 |
132 |
133 | def return_message(s):
134 | p = re.compile(r"> (.*?)同学")
135 | return p.findall(s).pop()
136 |
137 |
138 | # 三个主要功能函数聚集
139 | def jksb(user: dict, data: dict):
140 | html = login(user.get("no"), user.get("password"))
141 | enter(html)
142 | submit(data)
143 |
144 |
145 | # main方法
146 | if __name__ == "__main__":
147 | try:
148 | jksb(user, data)
149 | except Exception as e:
150 | print(e)
151 | finally:
152 | input("Press Any Key")
153 |
--------------------------------------------------------------------------------