使用selecnium自动填写问卷

使用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!妈妈再也不用担心我的健康打卡

参考链接:

webdriver.Chrome参数解释

python+selenium自动填写提交电子表单

Selenium Python 教程

Linux下安装chrome和chromedriver(Linux设置无头浏览器)

留下评论

Joey and Barry

我以为此时此刻全世界的热闹都只给你,全世界的烟火全都给你,所有的所有,不能更明亮了,就像你一直以来的那个样子。    ——艾伦