准备工作
1.针对自己的浏览器下载合适的driver,个人推荐Chrome浏览器和Chrome driver(下载地址:Chrome;Chrome driver)查看版本方式见下图:
将下载好的ChromeDriver.exe文件(不能包含在文件夹里)直接放在Chrome的根目录下一直到\Application:
(最新报错版本不符后需将Chromedriver.exe放在python路径下才能解决)
配置环境变量:此电脑→右击属性→高级系统设置→环境变量→用户变量→Path→编辑→新建,将上图的路径复制并成功新建
2.在IDE中直接pip install selenium库,用webdriver模块时必须使用from selenium import webdriver,测试一下输入以下代码:
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('http://www.baidu.com')
这里不能直接输入www网址,而必须加上http://或https://,否则报错selenium.common.exceptions.InvalidArgumentException: Message: invalid argument
(Session info: chrome=94.0.4606.81)
原因并不是版本不符合,而是url没有写协议名称
出现以下界面则成功
登录并打卡
根据自己的需要登录校园门户网站,F12开发者模式下查看并修改相应的定位元素等或许可以适用,具体selenium库的简单入门参考selenium库使用
def auto_check(username, password, to_email):
# 邮件标题,邮件内容,收件人邮箱,用户名,密码
browser = webdriver.Chrome()
browser.get('http://my.lzu.edu.cn:8080/login?service=http://my.lzu.edu.cn')
browser.find_element_by_xpath('//*[@id="username"]').click()
browser.find_element_by_xpath('//*[@id="username"]').send_keys(username)
browser.find_element_by_xpath('//*[@id="password"]').click()
browser.find_element_by_xpath('//*[@id="password"]').send_keys(password)
# 登录
browser.find_element_by_xpath("//button[@type='submit']").click()
time.sleep(3)
# 获取名字
name = browser.find_element_by_xpath('//*[@id="userName"]').get_attribute('textContent')
# 进入填报,鼠标悬停
move = browser.find_element_by_xpath('//span[contains(text(),"疫情上报基本信息填报")]')
ActionChains(browser).move_to_element(move).perform()
browser.find_element_by_xpath('//span[contains(text(),"进入")]').click()
# 提交
#第一次尝试,切换到iframe弹窗,用js执行点击
time.sleep(2)
iframe = browser.find_element_by_xpath("//*[@id='iframe']")
browser.switch_to.frame(iframe)
a = browser.find_element_by_xpath('//uni-button[contains(text(),"上报")]')
browser.execute_script("arguments[0].click();", a)
time.sleep(2)
print('success!')
time.sleep(3)
auto_email('打卡情况', name + ',今天已经帮你打卡啦\n' , to_email)
browser.quit()
由于可能会登入失败,可以等待数分钟后try…except…几次并设置相应的打卡失败邮件。其中采过的坑有
1.鼠标悬停
网页内的打卡设置为需要鼠标悬停在相应区域才会出现“进入”按钮并可以点击,如果直接执行click会报错找不到元素。
解决方法为先定位再悬停、点击:
move = browser.find_element_by_xpath('//span[contains(text(),"疫情上报基本信息填报")]')
ActionChains(browser).move_to_element(move).perform()
browser.find_element_by_xpath('//span[contains(text(),"进入")]').click()
2.切换到iframe弹窗,否则报错找不到元素;
解决方法为先定位弹窗再切换:
iframe = browser.find_element_by_xpath("//*[@id='iframe']")
browser.switch_to.frame(iframe)
具体切换参考文章:iframe切换
3.模拟js执行
貌似这个问题遇到的人比较少,往往报错找不到元素都会建议切换iframe并没有后续。。。所以我也查了好多资料,直到发现这个小细节:Please enable JavaScript to continue,需要用js点击元素。
解决方法为先定位按键再执行js点击:
a = browser.find_element_by_xpath('//uni-button[contains(text(),"上报")]')
browser.execute_script("arguments[0].click();", a)
具体参考文章:js执行点击
具体的账号信息我存储在txt文本里每次读取即可:
if __name__ == '__main__':
f = open('G:\PythonPractise\check.txt')
lines = f.readlines() #按行读取所有记录
scores = {}
for l in lines:
s = l.split()
scores[s[0]] = s[1:] #将每个人的记录存储为字典
for i in scores:
auto_check(i, scores[i][0], scores[i][1])
time.sleep(5)
f.close()
发送邮件及定时
每日打卡结果会通过我的QQ邮箱发给拜托我的小伙伴们,需要用到smpt模块和email模块,具体原理可参考文章:smtp发送邮件,这里就不过多赘述了。无聊的时候还加了一个查询每日天气的部分并加到邮件里和打卡情况一起发送,但其实只有我会每天看邮箱55555
def auto_email(title, message, to_email):
# 发信方的信息:发信邮箱,QQ邮箱SMTP授权码
from_addr = '用于发件的QQ邮箱'
password = 'SMTP授权码'
# 收信方邮箱
to_addr = to_email
# 发信服务器
smtp_server = 'smtp.qq.com'
# 邮箱正文内容,第一个参数为内容,第二个参数为格式(plain 为纯文本),第三个参数为编码
msg = MIMEText(message, 'plain', 'utf-8')
# 邮件头信息
msg['From'] = Header(from_addr)
msg['To'] = Header(to_addr)
msg['Subject'] = Header(title)
# 开启发信服务,这里使用的是加密传输
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()
定时的话我选择使用Windows的定时计划(反正实验室的电脑几乎不怎么关机 )将脚本保存为.py文件,具体教程参考文章:Windows定时计划
这里需要注意的是程序或脚本一栏并非IDE路径,而是解释器路径,同时要确保该解释器中下载有selenium库