├── .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 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 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 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 29 | 30 | 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 | ~~这个脚本暂时没法用,使用时会显示![img.png](assets/img.png),个人猜测是加了参数校验~~ 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 | ![assets/image](assets/image.png) 43 | user和data均为字典,user是你的登录名和密码, data是最后填报的数据,每一项数据代表的含义都注释了,和填报的顺序完全一致 44 | 45 | ![](assets/20210823_152151_image.png) 46 | 可自行对比查看 47 | 48 | 别的数据无特别情况无需变动 之后把代码上传到~~云服务器上~~ 自己电脑上,设置一个定时任务, 然后就可以自动的帮你打卡了. 49 | 50 | ## 1.1 win10设置定时任务教程 51 | 52 | - 在win10右下角搜索**计算机管理** 53 | 54 | ![](assets/20210823_152753_image.png) 55 | 56 | - 选择**任务管理程序**->**任务管理程序库**->**Microsoft**->**Windows**,并单击**Windows** 57 | 58 | ![](assets/20210823_155142_image.png) 59 | - 右键选择**创建基本任务**,或者在右边栏找到**创建基本任务** 60 | 61 | ![](assets/20210823_155336_image.png) 62 | - **名称**和**描述**可以随意,这里以下图的名称和描述为例,点击下一步 63 | 64 | ![](assets/20210823_153454_image.png) 65 | - 频率选择**每天,下一步 66 | 67 | ![](assets/20210823_153558_image.png) 68 | - 开始时间选择一个,你们辅导员催你打卡的时间之前,👀️ 。这里以0:05为例,点击下一步 69 | 70 | ![](assets/20210823_153733_image.png) 71 | - 选择启动程序(其实也没得选,因为别的都弃用了,可以自己实现一个),选择下一步 72 | 73 | ![](assets/20210823_153947_image.png) 74 | - 重点来了,这里的**程序或脚本**选择你本地的python.exe文件的路径,如果不知道,可以去环境变量里查,如果还不知道,用everything之类的工具搜索一下python.exe吧。添加参数选择打卡的.py文件。这里的意思相当于是,你在cmd中输入 E:\Python37\python.exe E:\PythonProject\zzu_jksb.py。是真正的启动脚本。点击下一步 75 | 76 | ![](assets/20210823_154344_image.png) 77 | - 至此,检查一下,看有没有问题,触发器就是启动时间和频率,操作就是执行脚本。没有问题就完成即可。图中的画框部分建议勾上,然后对属性进行设置。当然不勾也行,后面也有办法打开属性设置对话框。 78 | 79 | ![](assets/20210823_155602_image.png) 80 | - 剩下的步骤其实设置与否并不重要,但为了更稳定,建议设置上。具体如图 81 | 82 | ![](assets/20210823_155941_image.png) 83 | 84 | ![](assets/20210823_160011_image.png) 85 | 86 | 87 | ![](assets/20210823_160040_image.png) 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 | --------------------------------------------------------------------------------