前言:基于 selenium time模块
1 import time 2 from selenium import webdriver 3 from selenium.webdriver.common.by import By 4 from selenium.webdriver.common.keys import Keys
首先使用Google Chrome浏览器打开学校防疫健康打卡系统页面,其次分别检查 学号 密码 登录
所对应网页中div标签下的name值(当然也可以使用Xpath定位以提高准确性,防止页面中其它name元素的干扰)以实现第一步的自动登录。
1 driver.find_element(By.NAME,'xh').send_keys('username') 2 driver.find_element(By.NAME,'mm').send_keys('password') 3 driver.find_element(By.NAME,'Button1').click()
搞完第一步的模拟登录后,再来分析下一页面的结构,在这一面不需要下滑页面所以可以直接锁定检查“每日打卡”这个按钮,
观察之后发现这个i标签中没有存在 class name、name、id, 所以要用到Xpath实现元素的直接定位。
1 driver.find_element(By.XPATH,'/html/body/div[2]/div/div[3]/div/a[1]/i').click()
继续分析下一页面的构成元素,通过对两个目标的检查后发现和上一页的“每日打卡”按钮一样只能使用Xpath来进行元素定位
1 driver.find_element(By.XPATH,'//*[@id="form1"]/div[4]/ul/li/label/div[1]/i').click() 2 driver.find_element(By.XPATH,'//*[@id="form1"]/div[5]').click()
继续分析下一页,检查发现这一页11个按钮元素依旧只能使用Xpath来进行元素的定位,
检查最后的"提交打卡(今日已打卡)"观察到div标签下有name值,使用name值来进行元素定位。
1 # 杭州健康码每日汇报(健康码动态变化,打卡前请先确认) 2 # 绿码(杭州/绍兴健康码) 3 driver.find_element(By.XPATH,'//*[@id="form1"]/div[7]/ul/li[1]/label/div[1]/i').click() 4 time.sleep(0.5) 5 # 是否体温>37.3℃ 6 # 否 7 driver.find_element(By.XPATH,'//*[@id="form1"]/div[9]/ul/li[1]/label/div[1]/i').click() 8 time.sleep(0.5) 9 # 目前身体健康状况? 10 # 健康 11 driver.find_element(By.XPATH,'//*[@id="form1"]/div[11]/ul/li[1]/label/div[1]/i').click() 12 time.sleep(0.5) 13 # 是否接触了疑似或确诊病例? 14 # 无 15 driver.find_element(By.XPATH,'//*[@id="form1"]/div[13]/ul/li[1]/label/div[1]/i').click() 16 driver.find_element(By.XPATH,'/html/body').send_keys(Keys.SPACE) 17 time.sleep(1) 18 19 # 是否居家医学观察? 20 # 否 21 driver.find_element(By.XPATH,'//*[@id="form1"]/div[15]/ul/li[1]/label/div[1]/i').click() 22 time.sleep(0.5) 23 # 目前是否位于国外、国内、中高风险区? 24 # 否 25 driver.find_element(By.XPATH,'//*[@id="form1"]/div[21]/ul/li[1]/label/div[1]/i').click() 26 time.sleep(0.5) 27 # 14天内是否去过国外、国内、中高风险区? 28 # 否 29 driver.find_element(By.XPATH,'//*[@id="form1"]/div[23]/ul/li[1]/label/div[1]/i').click() 30 time.sleep(0.5) 31 # 14天内是否接触国外、国内、中高风险区出来的人员? 32 # 否 33 driver.find_element(By.XPATH,'//*[@id="form1"]/div[25]/ul/li[1]/label/div[1]/i').click() 34 time.sleep(0.5) 35 # 14天内从异地返回杭州(或绍兴上虞)? 36 # 就在杭州(或绍兴上虞)本地,未外出 37 driver.find_element(By.XPATH,'//*[@id="form1"]/div[27]/ul/li[1]/label/div[1]/i').click() 38 driver.find_element(By.XPATH,'/html/body').send_keys(Keys.SPACE) 39 time.sleep(1) 40 41 # 目前睡眠质量、精神状态? 42 # 很好 43 driver.find_element(By.XPATH,'//*[@id="form1"]/div[29]/ul/li[1]/label/div[1]/i').click() 44 time.sleep(0.5) 45 # 新冠疫苗接种情况? 46 # 已接种第二针 47 driver.find_element(By.XPATH,'//*[@id="form1"]/div[31]/ul/li[3]/label/div[1]/i').click() 48 time.sleep(1)
"提交打卡(今日已打卡)"按钮
1 driver.find_element(By.NAME,'Button1').click()
到此基本的页面元素分析算是完成了。
回过头来发现学校的打卡页面是内嵌式的(网页页面滑动滑块也是内嵌式的)
那么在模拟点击11个选择按钮的期间就不能根据 滚动页面至可见元素 windows.scrollBy(x,y)这个简单的方法操作了。
在学过的web前端知识中,页面下滑的滚动条不属于页面元素。例外的是如果有网页内嵌div中滚动条是可以控制的。
走到此验证学校的网页是否有内嵌div中的滚动条
检查可知在div标签中没有特殊的 class name ,id 值。
为进一步验证打开network 找到网页的css样式表发现依然没有 只有被隐藏了的overflow(上溢)
这个地步真让人上头,在py交流群中大佬建议使用repath通过层级定位一层一层锁死,Beautiful Soup抓取数据,Dom树对网页中的标签、属性、内容等进行 访增删改 操作。
好吧,作为菜鸟小白大佬们的这种算法方法自己去看文档属实是搞不明白。
挠头想啊又想既然可以模拟操作网页,那么是不是也可以操作键盘,模拟控制键盘的空格键从而进行空格下拉网页。翻文档找帖子可算找到方法了
好的,到此可算终于解决下拉网页的操作了。
最后就是设置time模块里的休眠方法来配合调式空格键下滑网页的点击操作(点击按钮选项和下滑网页的时间间隔)。
大功告成,完整的模拟实现了学校防疫健康的自动打卡。
最后 最后 上源码!!!
1 #coding:utf-8 2 import time 3 from selenium import webdriver 4 from selenium.webdriver.common.by import By 5 from selenium.webdriver.common.keys import Keys 6 7 # 模拟登录学校防疫健康打卡系统 8 9 # 无头浏览器 10 # url = '学校防疫健康打卡系统浏览器地址' 11 # opt = webdriver.ChromeOptions() 12 # opt.add_argument('--headless') 13 # opt.add_argument('--disable--gpu') 14 # driver = webdriver.Chrome(chrome_options=opt) 15 # driver.get(url) 16 17 # 有头浏览器 18 url = '学校防疫健康打卡系统浏览器地址' 19 20 driver = webdriver.Chrome() 21 22 driver.get(url) 23 24 driver.find_element(By.NAME,'xh').send_keys('username') 25 driver.find_element(By.NAME,'mm').send_keys('password') 26 driver.find_element(By.NAME,'Button1').click() 27 28 driver.find_element(By.XPATH,'/html/body/div[2]/div/div[3]/div/a[1]/i').click() 29 driver.find_element(By.XPATH,'//*[@id="form1"]/div[4]/ul/li/label/div[1]/i').click() 30 driver.find_element(By.XPATH,'//*[@id="form1"]/div[5]').click() 31 32 # 杭州健康码每日汇报(健康码动态变化,打卡前请先确认) 33 # 绿码(杭州/绍兴健康码) 34 driver.find_element(By.XPATH,'//*[@id="form1"]/div[7]/ul/li[1]/label/div[1]/i').click() 35 time.sleep(0.5) 36 # 是否体温>37.3℃ 37 # 否 38 driver.find_element(By.XPATH,'//*[@id="form1"]/div[9]/ul/li[1]/label/div[1]/i').click() 39 time.sleep(0.5) 40 # 目前身体健康状况? 41 # 健康 42 driver.find_element(By.XPATH,'//*[@id="form1"]/div[11]/ul/li[1]/label/div[1]/i').click() 43 time.sleep(0.5) 44 # 是否接触了疑似或确诊病例? 45 # 无 46 driver.find_element(By.XPATH,'//*[@id="form1"]/div[13]/ul/li[1]/label/div[1]/i').click() 47 driver.find_element(By.XPATH,'/html/body').send_keys(Keys.SPACE) 48 time.sleep(1) 49 50 # 是否居家医学观察? 51 # 否 52 driver.find_element(By.XPATH,'//*[@id="form1"]/div[15]/ul/li[1]/label/div[1]/i').click() 53 time.sleep(0.5) 54 # 目前是否位于国外、国内、中高风险区? 55 # 否 56 driver.find_element(By.XPATH,'//*[@id="form1"]/div[21]/ul/li[1]/label/div[1]/i').click() 57 time.sleep(0.5) 58 # 14天内是否去过国外、国内、中高风险区? 59 # 否 60 driver.find_element(By.XPATH,'//*[@id="form1"]/div[23]/ul/li[1]/label/div[1]/i').click() 61 time.sleep(0.5) 62 # 14天内是否接触国外、国内、中高风险区出来的人员? 63 # 否 64 driver.find_element(By.XPATH,'//*[@id="form1"]/div[25]/ul/li[1]/label/div[1]/i').click() 65 time.sleep(0.5) 66 # 14天内从异地返回杭州(或绍兴上虞)? 67 # 就在杭州(或绍兴上虞)本地,未外出 68 driver.find_element(By.XPATH,'//*[@id="form1"]/div[27]/ul/li[1]/label/div[1]/i').click() 69 driver.find_element(By.XPATH,'/html/body').send_keys(Keys.SPACE) 70 time.sleep(1) 71 72 # 目前睡眠质量、精神状态? 73 # 很好 74 driver.find_element(By.XPATH,'//*[@id="form1"]/div[29]/ul/li[1]/label/div[1]/i').click() 75 time.sleep(0.5) 76 # 新冠疫苗接种情况? 77 # 已接种第二针 78 driver.find_element(By.XPATH,'//*[@id="form1"]/div[31]/ul/li[3]/label/div[1]/i').click() 79 time.sleep(1) 80 81 # 操作异常 82 try: 83 # 最后提交 84 driver.find_element(By.NAME,'Button1').click() 85 86 except Exception as e: 87 print(e) 88 89 finally: 90 # 退出浏览器 91 driver.quit() 92