1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 易班打卡——自动填写健康日报

易班打卡——自动填写健康日报

时间:2021-11-03 23:43:41

相关推荐

易班打卡——自动填写健康日报

易班自动填写每日任务

分析使用Chrome访问易班校本化接口获取实现相关类users.json格式实例在main函数中从users.json读取账号信息远程服务器运行本地自动运行

以下提交日报的内容已失效:可以去看/ye-qiuming/nnu_yiban

分析

首先,要想使用浏览器登陆易班,我们需要一个特定的请求头.登陆时,易班中的js代码会对window.navigator进行检查设备是否为手机.登录过程通过简单的发送请求难以获取到Cookie,因为这其中有很多JS代码需要运行.所以应该使用无头浏览器获取到Cookie,之后在使用Cookie调用易班的接口.无头浏览器,笔者使用Python中的selenium,发送请求,笔者使用requests.

使用Chrome访问易班校本化

设置请求头

用户代理字符串设置为Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 yiban_iOS/5.02. 使用Chrome移动端体调试功能

访问/#/

接口获取

易班需要的user-agent的值为:

Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 yiban_iOS/5.0

获取未完成任务:/officeTask/client/index/uncompletedList

方法: GET

参数:StartTime:-08-13,查询的起始日期,后面可以加上时间,

参数:EndTime: -08-27,查询的终止日期,后面可以加上时间.

参数:CSRF:校验身份的参数,在易班的API都有提交任务:/workFlow/c/my/apply/*****(这个跟的是工作流ID)

方法:POST

参数:CSRF:校验身份的参数,在易班的API都有,

表单类型:“Content-Type”: “application/x-www-form-urlencoded”,

提交的数据格式:data=日报的信息&extend(任务信息)从具体的任务ID(task_id)获取工作流ID(workflow_id):/officeTask/client/index/detail

方法:GET

参数:TaskId:任务ID

参数:CSRF:校验身份的字符串签名

实现相关类

import datetimeimport jsonimport timefrom urllib.parse import quotefrom selenium import webdriverfrom selenium.webdriver.support.ui import WebDriverWaitimport requestsclass YiBanHelper:def __init__(self, **args):# 使用用户名或密码或者cookie初始化,优先使用cookieassert ('phpsessid' and 'csrf_token' in args.keys()) or ('username' and 'password' in args.keys()), "参数错误"# 初始化未完成的任务self.uncompletedTasks = None# self.wf_id = ""if 'phpsessid' and 'csrf_token' in args.keys():self.cookie = {"phpsessid": args.get('phpsessid'), "csrf_token": args.get('csrf_token')}returnelif 'username' and 'password' in args.keys():# 添加chrome的参数options = webdriver.ChromeOptions()# 使用无头模式options.add_argument('--headless')# 禁用GPUoptions.add_argument('--disable-gpu')# 添加请求头,这一项很重要options.add_argument('user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, ''like Gecko) ''Mobile/15E148 yiban_iOS/5.0')# 或者 使用下面的设置, 提升速度options.add_argument('blink-settings=imagesEnabled=false')driver = webdriver.Chrome(executable_path="driver/chromedriver.exe", options=options)driver.get("/#/")# 等待出现指定的元素,最多等待10sWebDriverWait(driver, 10).until(lambda d: d.find_element_by_id("oauth_uname_w"))un = driver.find_element_by_id("oauth_uname_w")# 填写用户名和密码,点击登陆按钮un.send_keys(args.get('username'))password = driver.find_element_by_id("oauth_upwd_w")password.send_keys(args.get('password'))btn = driver.find_element_by_css_selector("button.oauth_check_login")btn.click()# 等待页面跳转完成WebDriverWait(driver, 10).until(lambda d: str(driver.current_url).startswith(""))# 稍稍等待1s,目的是等待页面的js执行完成,cookie才能正确的更新time.sleep(1)# 获取cookiephpsessid = driver.get_cookie("PHPSESSID").get('value')token = driver.get_cookie("csrf_token").get('value')self.cookie = {"phpsessid": phpsessid, "csrf_token": token}if args.pop("show_cookie", False):print("PHPSESSID的值是: " + phpsessid)print("CSRF_TOKEN的值是: " + token)driver.close()# 查询未完成的任务def query_completed_tasks(self, **args):assert 'phpsessid' and 'csrf_token' in self.cookietoday = datetime.date.today()tomorrow = str(today + datetime.timedelta(days=1))before = str(today - datetime.timedelta(days=14))# 向接口发送请求res = requests.get("/officeTask/client/index/uncompletedList",params={"StartTime": args.pop("start_time", before),"EndTime": args.pop("end_time", tomorrow),"CSRF": self.cookie.get('csrf_token')},cookies={"PHPSESSID": self.cookie.get('phpsessid'),"csrf_token": self.cookie.get('csrf_token')},headers={"Origin": "","User-Agent": 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS ''X) AppleWebKit/605.1.15 (KHTML, ''like Gecko) ''Mobile/15E148 yiban_iOS/5.0'})# 尝试将结果json化try:result = json.loads(res.text)if result.get("code") == 0:self.uncompletedTasks = result.get('data')if result.get('code') == 999:print("登陆失败")# 下面这个是为了在提交信息的时候报错self.uncompletedTasks = []except ValueError:print("Cookies或许出现错误, 可能需要重新获取Cookie")# 提交任务,info是个人的日报信息,extend会自动生成def submit_task(self, info: dict = None, **kwargs):assert 'wf_id' and "auto_wf_id" in kwargs, "缺少工作流ID"# 首先查询完成的信息,初始化必要的参数self.query_completed_tasks(**kwargs)if len(self.uncompletedTasks) == 0:print("没有需要完成任务")returnfor task in self.uncompletedTasks:start_time = task.get('StartTime')if int(time.time()) < int(start_time):print("任务尚未开始")continueelse:task_id = task.get('TaskId')task_title = task.get("Title")extent = {"TaskId": task_id,"title": "任务信息","content": [{"label": "任务名称", "value": task_title}, {"label": "发布机构", "value": "学生工作处"}]}print("任务id: " + task_id)data = f"data={quote(json.dumps(info))}&extend={quote(json.dumps(extent))}"wf_id = ""if 'wf_id' in kwargs:wf_id = kwargs.get("wf_id")elif kwargs.get('auto_wf_id'):wf_id = self.get_task_wf_id(task_id=task_id)else:raise ValueError("未初始化WF_ID")result = requests.post("/workFlow/c/my/apply/" + wf_id,params={"CSRF": self.cookie.get("csrf_token")},headers={"Origin": "","Content-Type": "application/x-www-form-urlencoded","sec-ch-ua": "","sec-ch-ua-mobile": "?1","User-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS ""X) AppleWebKit/605.1.15 (KHTML, like Gecko) ""Mobile/15E148 yiban_iOS/5.0","Sec-Fetch-Site": "same-site","Sec-Fetch-Mode": "cors","Sec-Fetch-Dest": "empty","Referer": "/","Accept-Encoding": "gzip, deflate, br","Accept-Language": "zh-CN,zh;q=0.9"},cookies={"PHPSESSID": self.cookie.get('phpsessid'),"csrf_token": self.cookie.get('csrf_token')},data=data)if result.json().get('data') != '':print("提交成功:", result.json())def get_task_wf_id(self, task_id: str):res = requests.get("/officeTask/client/index/detail?TaskId=" + task_id,params={"CSRF": self.cookie.get('csrf_token')},cookies={"PHPSESSID": self.cookie.get('phpsessid'),"csrf_token": self.cookie.get('csrf_token')},headers={"Origin": "","User-Agent": 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS ''X) AppleWebKit/605.1.15 (KHTML, ''like Gecko) ''Mobile/15E148 yiban_iOS/5.0'})res_json = res.json()if res_json.get('code') == 0:return res_json.get('data').get('WFId')else:raise ValueError("没有成功的获取到返回结果")

users.json格式实例

{"workflow_id": "acd15f15b8b1d00177bc7f5b76825e6f","userInfos": [{"name": "wuwuwu","username": "手机号","password": "密码","dataJson": {"dc4ca3f85c74379af3fad9e4396dcb4a": "在江苏省外","e5e61e20a56c437a7ca40a328cf71dfe": "是","93f875901b6189fe983e328a0aae6fc3": ["安徽省","胖子市","瘦子县"],"663e407b1020897215370034756eb8ad": "北苑","66d9ca12eec4878d4f3b552a619e22f8": "32-213","a8b7d6f1632bc07f55fc2acbf651aae5": "良好,无特殊病情","a069e4b52079413679cc71a8f70c7edf": "请假离开学校外出","664d3c096eefcdc6f80e35b1c701a227": "36.6°-36.9°(正常体温)","4b8f8e82a032908896b5d612e8c67888": "36.6°-36.9°(正常体温)","3a4882f7345c05cafa2fe461d3565ea3": "无","45ba114671d08b3a774bd28db02d0be0": ["是"],"0a8a469c2c3c8bf2aa9ee4f46af5447c": 2}},{"name": "yingyingying","username": "手机号","password": "密码","dataJson": {"dc4ca3f85c74379af3fad9e4396dcb4a": "在江苏省外","e5e61e20a56c437a7ca40a328cf71dfe": "是","93f875901b6189fe983e328a0aae6fc3": ["河北省","嘤嘤嘤市","呜呜呜县"],"663e407b1020897215370034756eb8ad": "北苑","66d9ca12eec4878d4f3b552a619e22f8": "34-226","a8b7d6f1632bc07f55fc2acbf651aae5": "良好,无特殊病情","a069e4b52079413679cc71a8f70c7edf": "请假离开学校外出","664d3c096eefcdc6f80e35b1c701a227": "36.6°-36.9°(正常体温)","4b8f8e82a032908896b5d612e8c67888": "36.6°-36.9°(正常体温)","3a4882f7345c05cafa2fe461d3565ea3": "无","45ba114671d08b3a774bd28db02d0be0": ["是"],"0a8a469c2c3c8bf2aa9ee4f46af5447c": 2}},{"name": "Cheems","username": "手机号","password": "密码","dataJson": {"dc4ca3f85c74379af3fad9e4396dcb4a": "在江苏省外","e5e61e20a56c437a7ca40a328cf71dfe": "是","93f875901b6189fe983e328a0aae6fc3": ["安徽省","巢湖市","哈哈县"],"663e407b1020897215370034756eb8ad": "北苑","66d9ca12eec4878d4f3b552a619e22f8": "34-222","a8b7d6f1632bc07f55fc2acbf651aae5": "良好,无特殊病情","a069e4b52079413679cc71a8f70c7edf": "在家学习","664d3c096eefcdc6f80e35b1c701a227": "36.6°-36.9°(正常体温)","4b8f8e82a032908896b5d612e8c67888": "36.6°-36.9°(正常体温)","45ba114671d08b3a774bd28db02d0be0": ["是"],"0a8a469c2c3c8bf2aa9ee4f46af5447c": 2}}]}

在main函数中从users.json读取账号信息

非常简单,新建个对象,调用一下函数就可以了

def do_task():with open("src/users.json", 'r', encoding='utf8') as f:users = json.load(f)infos = users.get("userInfos")for user in infos:print("当前用户:", user.get("name"))yiban = YiBanHelper(password=user.get("password"), username=user.get("username"), show_cookie=True)person_info = user.get("dataJson")yiban.submit_task(info=person_info, auto_wf_id=True)# Press the green button in the gutter to run the script.if __name__ == '__main__':do_task()

远程服务器运行

编写shell,将每次的输出以日期命名放在一个文件夹中.在Linux中创建定时任务,在任务开始的时候自动运行,然后就彻底告别易班了!!

cd 相关目录current_date=`date '+%m-%d'`current_time=`date`result=`python3 "main.py"`mkdir -p logecho -e "${current_time}\n $result \n" >> "log/${current_date}.log"

本地自动运行

当然,如果你是Mac或者Linux用户都是可以创建自动化任务的,在终端中输入crontab -e来编辑定时任务。

如果你是windows用户的话,win+R,输入taskschd.msc可以创建windows的自动化任务

备注:本方法在NJNU已经失效,因为对发送的数据进行了加密。但是这只是一个日报功能,其他的晚点签到仍然可以使用类似的方法实现全自动签到。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。