重构一时爽, 构错火葬场
重构的起因是因为有一天任务计划程序显示0X1 但并没有收到邮件,
很显然,
由于忽忽悠的采用了比肩国际一流游戏厂商的极为先进的生物(土豆)供电服务器,
导致经常出现难以预料的情况(喂,
明明是你的脚本鲁棒性不够好嘛).
开搞之前
首先分析需求.
之前的脚本发送的邮件中并没有最后打卡时间, 又由于鲁棒性的不足,
导致并不能完全通过收到邮件来判断是否成功打卡.
同样, 之前的脚本并没有对异常情况的处理机制(没错,
我就是能卡你半个小时), 导致出现异常时不能收到邮件反馈.
时间获取
历史填报会打开新的标签页, 所以就需要切换标签页.
1 2 3 4 tabs = driver.window_handles driver.switch_to.window(tabs[1 ])
接下来就是老套路, 定位元素, 获取值, Xpath走起. 1 table = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.XPATH, '//*[@id="countTableBody"]/tr[1]/td[1]' )))
那么如何获取当前时间呢? 我们可以使用datetime库. 1 today = datetime.datetime.now()
时间处理
datetime库中提供了一些函数来对时间进行处理, 比如从字符串中提取时间,
将时间转换为字符串. 1 2 3 4 today = datetime.datetime.now() today_date = today.strftime("%Y-%m-%d" ) newest_time = datetime.datetime.strptime(table.text, "%Y-%m-%d %H:%M:%S" ) newest_date = newest_time.strftime("%Y-%m-%d" )
异常处理
通过try-except语句可以实现对异常状况的处理, 首先执行try下的语句块,
如果出现异常就跳转执行except下的语句块.
既然做了异常处理, 就没有必要设置1800s的延迟了,
调成180s以示对极为先进的生物供电服务器的尊敬.
完整代码
这里对敏感信息做了模糊处理, 请根据实际情况自行替换。
点我查看完整代码
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 from selenium import webdriverfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.common.by import Byimport timeimport datetimeimport smtplibfrom email.mime.text import MIMETextfrom email.header import Headerhead = '今日疫情填报情况' mail_text = '无法获取历史填报信息' try : driver = webdriver.Firefox() url = 'http://ids.hhu.edu.cn/amserver/UI/Login?goto=http://form.hhu.edu.cn:80/pdc/form/list' driver.get(url) driver.maximize_window() username = driver.find_element_by_id('IDToken1' ) stu_number = '***' username.send_keys(stu_number) stu_password = '***' password = driver.find_element_by_id('IDToken2' ) password.send_keys(stu_password) sign_inBtn = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.XPATH, "//*[contains(@onclick, 'defaultSubmit()')]" ))) driver.execute_script('defaultSubmit()' ) goto = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.CLASS_NAME, "datav-flex-box" ))) goto.click() submit = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.ID, "saveBtn" ))) time.sleep(5 ) driver.execute_script('save()' ) WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.CLASS_NAME, "panel-body" ))) driver.back() driver.back() driver.back() driver.back() driver.back() time.sleep(5 ) username = driver.find_element_by_id('IDToken1' ) password = driver.find_element_by_id('IDToken2' ) password.send_keys(stu_password) sign_inBtn = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.XPATH, "//*[contains(@onclick, 'defaultSubmit()')]" ))) driver.execute_script('defaultSubmit()' ) goto = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.CLASS_NAME, "datav-flex-box" ))) goto.click() history = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.ID, "showHistoryBtn" ))) driver.execute_script('showFormFilled()' ) tabs = driver.window_handles time.sleep(5 ) driver.switch_to.window(tabs[1 ]) table = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.XPATH, '//*[@id="countTableBody"]/tr[1]/td[1]' ))) time.sleep(5 ) today = datetime.datetime.now() today_date = today.strftime("%Y-%m-%d" ) newest_time = datetime.datetime.strptime(table.text, "%Y-%m-%d %H:%M:%S" ) newest_date = newest_time.strftime("%Y-%m-%d" ) if today_date == newest_date: mail_text = '今日疫情填报已完成, ' else : mail_text = '今日疫情填报未完成, ' mail_text += '最后填报时间: ' + table.text except : head = '疫情填报异常' try : driver = webdriver.Firefox() url = 'http://ids.hhu.edu.cn/amserver/UI/Login?goto=http://form.hhu.edu.cn:80/pdc/form/list' driver.get(url) driver.maximize_window() username = driver.find_element_by_id('IDToken1' ) stu_number = '****' username.send_keys(stu_number) stu_password = '****' password = driver.find_element_by_id('IDToken2' ) password.send_keys(stu_password) sign_inBtn = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.XPATH, "//*[contains(@onclick, 'defaultSubmit()')]" ))) driver.execute_script('defaultSubmit()' ) goto = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.CLASS_NAME, "datav-flex-box" ))) goto.click() history = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.ID, "showHistoryBtn" ))) driver.execute_script('showFormFilled()' ) tabs = driver.window_handles driver.switch_to.window(tabs[1 ]) table = WebDriverWait(driver, 180 ).until(EC.presence_of_element_located((By.XPATH, '//*[@id="countTableBody"]/tr[1]/td[1]' ))) time.sleep(5 ) today = datetime.datetime.now() today_date = today.strftime("%Y-%m-%d" ) newest_time = datetime.datetime.strptime(table.text, "%Y-%m-%d %H:%M:%S" ) newest_date = newest_time.strftime("%Y-%m-%d" ) if today_date == newest_date: mail_text = '今日疫情填报已完成, ' else : mail_text = '今日疫情填报未完成, ' mail_text += '最后填报时间: ' + table.text head += ', 获取填报信息正常' except : head += ', 获取填报信息异常' from_addr = '***@qq.com' password = '***' to_addr = '***@qq.com' smtp_server = 'smtp.qq.com' print (mail_text)msg = MIMEText(mail_text, 'plain' , 'utf-8' ) msg['From' ] = Header(from_addr) msg['To' ] = Header(to_addr) msg['Subject' ] = Header(head) server = smtplib.SMTP_SSL(smtp_server) server.connect(smtp_server, 465 ) server.login(from_addr, password) server.sendmail(from_addr, to_addr, msg.as_string()) server.quit() driver.quit()