Python学习笔记--每日健康打卡及离校报备

2024-01-07 10:58

本文主要是介绍Python学习笔记--每日健康打卡及离校报备,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

每日健康打卡及出校报备

  • 前言
  • 一、通过selenium实现自动化外出报备
    • 1.1 思路
    • 1.2 selenium相关
    • 1.3 xpath的获取
    • 1.4 通过xpath操作相关元素
  • 二、通过requests库实现自动化健康打卡
    • 2.1 思路
    • 2.2 requests.post()的使用
    • 2.3 登录
    • 2.4 获取日期及打卡状态
    • 2.5 提交数据

前言

距离上次练习已经过去了大半年,现在终于有时间接着进行一些其他方面的练习了。上次的弹幕练习属于为爱发电,这回更注重实用性,在练习的同时顺便解决一下生活中的实际问题,一举两得~

这次主要有两个内容,分别是学校的每日健康打卡以及外出报备的自动化处理,通过seleniumrequest库两种不同的方法实现,省去了每次都要手动填表的麻烦。如果有时间,还会涉及到UI以及exe打包相关内容。

话不多说,开始!

一、通过selenium实现自动化外出报备

1.1 思路

报备出校流程为:登录-填表-提交-得到结果,其中表格部分内容为自动生成,其余通过selenium配合xpath即可完成。

虽然也可以用requests实现,但相对要麻烦很多(登录就要麻烦不少,headers的选择,密码也经过MD5处理过。。。)

1.2 selenium相关

要使用selenium,必须配置好系统环境变量以及对应浏览器的webdriver,且版本要相匹配。

例如要使用Chrome浏览器则需要对应的driver,国内镜像地址为:下载地址

需要注意的是,如果电脑上有多个Chrome核心的浏览器,在使用以下代码时可能会出现调用失败的情况:

driver = webdriver.Chrome()

此时指定webdriver所在路径即可解决:

driver = webdriver.Chrome(r'X:\xxxxxxx\chromedriver.exe')

正常运行时,浏览器页面会一直出现,便于观察代码执行过程,这在测试阶段是十分必要的。当程序测试完毕后,就不再需要监测过程,得到结果便可。此时可以使浏览器在后台静默运行,不再出现浏览器窗口,代码如下:

option = webdriver.ChromeOptions()
option.add_argument('headless')  # 设置静默执行
option.add_argument("window-size=1920x1080")  # 最大化,便于截图
driver = webdriver.Chrome(r'X:\xxxxxxx\chromedriver.exe', options=option)

当使用静默模式运行时,最大化窗口不能使用driver.maximize_window(),而要用option.add_argument("window-size=Width x Height"),如1920x1080。

至此,driver相关设置完成。

1.3 xpath的获取

通过find_element_by_xpath()可以很方便的实现元素的定位,只需找出对应元素的xpath即可进行操作。通过浏览器查看网页源码即可获取目标元素的xpath:

从中选取需要的xpath

得到xpath如下:

	uid_xpath = './/input[@name="username"]'pwd_xpath = './/input[@name="password"]'button1_xpath = './/span[@class="password_arrows"]'button2_xpath = './/a[@id="preview_start_button"]'phonenum_xpath = './/input[@name="fieldSQlxdh"]'reason_xpath = './/textarea[@name="fieldSQqjsy"]'schedule_xpath = './/textarea[@name="fieldSQxcap"]'button3_xpath = './/label[@for="V1_CTRL69"]'timestart_xpath = './/input[@name="fieldQJqjkssj"]'timeend_xpath = './/input[@name="fieldQJqjjssj"]'dayend_xpath = './/input[@name="fieldQJqjrqTo"]'button4_xpath = './/a[@class="command_button_content"]'button5_xpath = './/button[@class="dialog_button default fr"]'

以上为需要填入数据或选择类型以及提交按钮的xpath。

1.4 通过xpath操作相关元素

通过find_element_by_xpath()定位元素后,即可进行相关操作。本次主要涉及点击清空内容以及填写数据这三种操作,分别对应:

	driver.find_element_by_xpath().click()driver.find_element_by_xpath().clear()driver.find_element_by_xpath().send_keys()

需要进行填写的数据有:账号,密码,手机号,出校原因,出校安排,开始时间,结束时间以及结束日期,离校类型为点选。

登陆界面

填报界面

需要注意的是,若操作速度过快可能会因为元素未加载完成无法定位而导致失败,因此需要进行延时处理。

最简单的办法是通过time.sleep()进行等待,每次执行语句前后强制等待,确保相应元素有足够的时间完成加载:

	time.sleep(1)driver.find_element_by_xpath(uid_xpath).clear()  #清空已存在内容driver.find_element_by_xpath(uid_xpath).send_keys(username)  #传入用户名time.sleep(1)driver.find_element_by_xpath(pwd_xpath).clear()driver.find_element_by_xpath(pwd_xpath).send_keys(pwd)  #传入密码time.sleep(1)driver.find_element_by_xpath(button1_xpath).click()  #登录time.sleep(5)driver.find_element_by_xpath(button2_xpath).click()  #开始办理time.sleep(2)driver.find_element_by_xpath(phonenum_xpath).clear()   #手机号driver.find_element_by_xpath(phonenum_xpath).send_keys(phonenum)time.sleep(1)driver.find_element_by_xpath(reason_xpath).clear()  #原因driver.find_element_by_xpath(reason_xpath).send_keys(reason)time.sleep(1)driver.find_element_by_xpath(schedule_xpath).clear()  #行程driver.find_element_by_xpath(schedule_xpath).send_keys(schedule)time.sleep(1)driver.find_element_by_xpath(button3_xpath).click()  #离校类型time.sleep(1)driver.find_element_by_xpath(timestart_xpath).clear()  #起始时间driver.find_element_by_xpath(timestart_xpath).send_keys(timestart)time.sleep(1)driver.find_element_by_xpath(timeend_xpath).clear()  #结束时间driver.find_element_by_xpath(timeend_xpath).send_keys(timeend)time.sleep(1)driver.find_element_by_xpath(dayend_xpath).clear()  #结束日期driver.find_element_by_xpath(dayend_xpath).send_keys(dayend)time.sleep(1)driver.find_element_by_xpath(button4_xpath).click()  #提交time.sleep(1)driver.find_element_by_xpath(button5_xpath).click()  #最终确定time.sleep(1)driver.find_element_by_xpath(button6_xpath).click()

可以发现,这种方式缺点很明显:

  1. 重复代码过多,不够简洁。
  2. 若设置较长等待时间会延长程序运行时间而降低效率,若等待时间过短则无法达到目的。

selenium的显式等待可以准确判断等待时间,既能达到确定元素的目的,也能缩短延时时间,提高效率,但其用法较为复杂,还需要导入相关的库:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

使用显式等待方式的同时,为精简代码,可以把不同元素及其对应的xpath存为dict,待填写数据存为list:

	xpath_dict = {'uid_xpath': './/input[@name="username"]',  # 账号'pwd_xpath': './/input[@name="password"]',  # 密码'button1_xpath': './/span[@class="password_arrows"]',  # 登录按钮'button2_xpath': './/a[@id="preview_start_button"]',  # 开始办理'phone_num_xpath': './/input[@name="fieldSQlxdh"]',  # 电话号码'reason_xpath': './/textarea[@name="fieldSQqjsy"]',  # 出校事由'schedule_xpath': './/textarea[@name="fieldSQxcap"]',  # 出校日程'button3_xpath': './/label[@for="V1_CTRL69"]',  # 离校类型'time_start_xpath': './/input[@name="fieldQJqjkssj"]',  # 开始时间'time_end_xpath': './/input[@name="fieldQJqjjssj"]',  # 结束时间'day_end_xpath': './/input[@name="fieldQJqjrqTo"]',  # 结束日期'button4_xpath': './/a[@class="command_button_content"]',  # 提交'button5_xpath': './/button[@class="dialog_button default fr"]'  # 最终确定}data_list = [username,pwd,phone_num,reason,schedule,time_start,time_end,day_end]

此处利用for循环即可自动判断操作类型为点击或填写数据,并按顺序自动完成。

	count = 0for i in xpath_dict:if 'button' in i:  # 判断操作类型try:WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, xpath_dict[i])))finally:driver.find_element_by_xpath(xpath_dict[i]).click()else:try:WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, xpath_dict[i])))finally:driver.find_element_by_xpath(xpath_dict[i]).clear()driver.find_element_by_xpath(xpath_dict[i]).send_keys(data_list[count])count += 1

填报完成后,可根据需要通过截图(driver.get_screenshot_as_file())等方式留存并发送报备结果,或继续填加自动运行等功能。

二、通过requests库实现自动化健康打卡

2.1 思路

这个项目利用requests库来进行处理,之前的练习主要使用了get(),本次则主要涉及post(),具体流程与上文相同,区别在于不使用selenium模拟操作,直接进行数据的获取与提交。

还有一个不使用selenium的原因是,打卡需要获取定位,然而pc端总是无法定位,只能换用requests的方法。

系统使用的是腾讯的api接口,通过抓包发现确实可以获取正确定位,但是系统却无法读取,原因未知。

在这里插入图片描述
位置都出来了,为什么不用呢。。。
在这里插入图片描述
通过多次抓包试验,最终确定整个打卡过程共存在三次post行为,分别为登录,请求日期以及提交,对应三个不同的url。其中登录和提交带有数据,请求日期为单纯的post。

2.2 requests.post()的使用

和get的用法差不多,以登陆系统为例,本次需要注意的有请求的headers以及data:

  1. headers必须包含Content-Type。涉及到的系统的数据交换都是以json格式进行的,必须声明Content-Type,否则会返回错误的response。
  2. data所传输的数据必须为json格式。一般post的数据有form datarequest payload两种形式,前者一般可以直接使用,而后者需要进行格式的转换。此处需要用到json.dumps()将python对象转换为json格式。(顺便一提,这系统登录时提交的密码是明文的,都不处理下吗。。。)

2.3 登录

登录时提交账号密码等数据即可:

	headers = {'User-Agent': 'xxx','Content-Type': 'application/json'}data_origin = {user_account,user_password}login_url = 'xxxxxxxx'login_res = requests.post(login_url, headers=headers, data=json.dumps(data_origin)) login_res_json = login_res.json()

在这里插入图片描述

通过返回的response可以判断登录是否成功,200为成功,其他则为不同情况的错误:

在这里插入图片描述

若不传入cookie,则会返回:{'code': 405, 'msg': '凭据已经过期,请重新认证', 'datas': ''}。这会导致请求日期和提交无法进行,因此需要在登陆后获取cookie并在接下来的post中传入。(尝试过单独使用session()而不传入cookie,无效,原因未知。)

	cookies = login_res.cookies  # 获取登陆后cookiecookie = requests.utils.dict_from_cookiejar(cookies)  # 转换为可传入参数格式

2.4 获取日期及打卡状态

在这里插入图片描述

在这里插入图片描述

可以看出,相关数据都储存在datas的hunch_list中,其中date1为打卡当天日期,state为打卡状态,1为已打卡,0为未打卡。

在这里插入图片描述

对日期进行请求:

	date_res = requests.post(date_url, headers=headers, cookies=cookie)date_res_json = date_res.json()

将date1提取出来,提交时要用到:

today = date_res_json['datas']['hunch_list'][0]['date1']

接下来根据state的值判断是否继续打卡:

	statue = 0  # 是否继续执行,0为继续if date_res_json['datas']['hunch_list'][0]['state'] == 1:statue += 1print('今日已打卡!')else:print('今日未打卡,将自动打卡。。。')

2.5 提交数据

在这里插入图片描述

提交时,数据主要包括两部分:date和punch_form。其中date的值就是之前提取过的date1,punch_form为需要进行填报的内容,包括所在地,联系方式,体温等。最后将这两部分数据打包提交即可:

在这里插入图片描述

    if statue == 0:res_submit = requests.post(submit_url, headers=headers, data=json.dumps(data_punch), cookies=cookie)res_submit_json = res_submit.json()if res_submit_json['code'] == 200:print('打卡成功!')else:print('打卡失败!')print('错误!:%s' % (res_submit_json['msg']))

这篇关于Python学习笔记--每日健康打卡及离校报备的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/579688

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识