使用selenium自动填写问卷
疫情反反复复,学校要求每天健康打卡,但是人懒怎么办呢,打卡是不可能打卡的,只好写个脚本了
1. 环境准备
(1) 因为要保持每天定时打卡,所以需要一台永不停机的机器
本文使用Linux(Red Hat 4.8.5-39)作为部署环境
(2) chrome以及ChromeDriver模拟用户,当然也可以选用别的浏览器
Linux安装最新的chrome
yum install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
安装必要的库
yum install mesa-libOSMesa-devel gnu-free-sans-fonts wqy-zenhei-fonts
安装ChromeDriver,ChromeDriver – WebDriver for Chrome 或 淘宝镜像 找到大于等于chrome版本的driver版本,以92.0.4515.43版本为例
wget http://npm.taobao.org/mirrors/chromedriver/92.0.4515.43/chromedriver_linux64.zip
下载后解压并建立软链接(driver要装在chrome目录下)
unzip chromedriver_linux64.zip
ln -s /opt/google/chrome/chromedriver /usr/bin/chromedriver #在/usr/bin/下创建链接文件供后续使用
(3) 发送邮件的第三方服务器
通过发送邮件的方式可以显示自己是否打卡成功。其实也能用系统自带的smtp服务,但有时会接收不到邮件,因此选用第三方。本文使用163邮箱作为发送方,qq邮箱作为接收方。
在163邮箱中找到设置,/POP3/SMTP/IMAP
设置选项,选择开启IMAP/SMTP服务,后续需要发送短信验证的操作,操作完成后复制登录授权码到本地供后续编码使用。
2. 开始编码
(1) 自动填写问卷
首先添加一些启动Chrome的配置,例如无头模式
,更多设置选项可 点击查阅 --headless
chrome_options = Options()
# chrome默认弹窗,不禁止会报错,本地测试可以删掉
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--headless')
#添加选项以及之前配置好的ChromeDriver路径
driver = webdriver.Chrome(options=chrome_options, executable_path='/usr/bin/chromedriver')
配置好后打开问卷
driver.get("https://stuhealth.jnu.edu.cn/#/login")
F12查看各个控件,根据不同的控件类型,实现不同的操作:
文本型(如:输入账号密码)
driver.find_element_by_id("zh").clear()
driver.find_element_by_id("zh").send_keys(str('id'))
按钮
driver.find_element_by_xpath("//button[text()='登录']").click()
下拉框的选择
如果是普通的下拉框可以通过Selenium中的Select模块进行选择
province = driver.find_element_by_id("selectProvinceJtzz")
Select(province).select_by_visible_text(account["province"])
但有的时候下拉框前端并不是通过select组件实现,因此可能需要模拟点击来实现
choose_country = driver.find_element_by_xpath("/html/body/app-root/app-index/div/div[1]/app-home/section/section/div/div/div/div/div/div[12]/div/span[1]/span/span[1]/span/span[2]")
choose_country.click()
country = driver.find_element_by_xpath("/html/body/span/span/span[2]/ul/li[39]")
country.click()
复选框
可以通过同名class进行定位,然后通过点击选项下标进行点击
#注意定位元素为列表时find_elements要加s
choose_campus = driver.find_elements_by_class_name("nonewline")
choose_campus[1].click() #对第二个选项进行点击
但上面的方法可能存在不同问题下,使用相同的class名的情况,会导致无法精确定位的问题,因此还是建议通过使用绝对路径等进行定位
city_wrapper = driver.find_element_by_xpath("/html/body/app-root/app-index/div/div[1]/app-home/section/section/div/div/div/div/div/div[9]/div/span/span/span[1]/span/span[2]")
city_wrapper.click()
还有诸如隐藏选项的定位等就在此不一一列举啦,方法总比困难多,遇到了在查查资料咯
(2) 发送邮件
这个主要配置好服务器就好咯
#发送端服务器
smtp = smtplib.SMTP_SSL('smtp.163.com')
#登录:前面配置好的发送端email和开通IMAP服务的授权码
smtp.login('发送端email', '登录授权码')
message = MIMEText('今日疫情打卡成功,请继续加油哦~', 'plain', 'utf-8')
#有时候会报错554 DT:SPM,所以Header最好按照格式,例Header('XXX@163.com', 'utf-8')
message['From'] = Header('Barry', 'utf-8')
message['To'] = Header('Joey', 'utf-8')
message['Subject'] = Header('健康问卷打卡', 'utf-8')
#具体执行时当然还得try-catch捕捉异常咯
smtp.sendmail('发送端emal', '接收端email', message.as_string())
(3) 在服务端配置命令
在命令行键入
编辑定时任务crontab -e
0 9 * * * /home/checkhealth/jnu_health_check_final.py
over!妈妈再也不用担心我的健康打卡
参考链接: