前言:基於 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