tags: python,selenium,linux
背景
学校放寒假了,又恢复了去年在家每天打卡的日常,今年就想研究一下怎么用python自动打卡并且放在linux服务器上定时运行,今天就分享一下我的实现方法。
bnuz打卡的网页地址:
http://xgfx.bnuz.edu.cn/xsdtfw/sys/emapfunauth/pages/welcome.do?service=%2Fxsdtfw%2Fsys%2Fswmxsyqxxsjapp%2F*default%2Findex.do%3FwxType%3D1
环境准备
-
谷歌浏览器
-
安装:
yum install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
-
查看谷歌版本号
google-chrome -version
-
下载对应版本谷歌浏览器驱动:
-
淘宝镜像地址:
http://npm.taobao.org/mirrors/chromedriver
-
选择对应的版本号后wget下载
wget https://cdn.npm.taobao.org/dist/chromedriver/88.0.4324.96/chromedriver_linux64.zip
- 下载完成后,解压,移动到/usr/bin下
unzip chromedriver_linux64.zip mv chromedriver /usr/bin/
- 查看chromedriver版本号
chromedriver --version
注意:驱动的版本号要和浏览器的版本号一致
(若使用别的浏览器则下载该浏览器的驱动)
- 下载selenium
pip install selenium
使用selenium结合XPATH操作元素
- 使用selenuim模拟点击、输入、清空等事件。
- 使用XPATH定位元素
-
如何确定XPATH?
可以自己通过dom确定,也可以使用谷歌浏览器自带的功能快速定位。使用谷歌浏览器快速得到XPATH优缺点
优点:
方便快捷,小白也能轻松上手
缺点:
①当页面元素会随着操作变化时,使用XPATH绝对定位可能会定位失败
②当页面有嵌套子页面的时候使用XPATH绝对定位会失败
但是selenuim可以通过多种方式定位元素,当无法使用XPATH的时候可以通过别的办法进行定位。- 谷歌快速得到 full XPATH的方法:
F12打开开发者模式
- 谷歌快速得到 full XPATH的方法:
-
实现代码
特别提醒:本代码仅用于自学,禁止商用!如身体健康出现异常请及时停用自觉向学校报备!本人概不负责。
#Language:Python
#Author: Lily
#Date:2021/1/20
#注:本代码是基于用户之前已经手动提交过“每日报平安”的基础上的,
#因为服务器会保存用户的重要信息,如:家庭住址,所在地区等,
#所以这篇代码就可不必填这些敏感信息。
#特别提醒:本代码仅用于自学,禁止商用!如身体健康出现异常请及时停用自觉向学校报备!本人概不负责。
from selenium import webdriver
from time import sleep
from email.header import Header
from smtplib import SMTP_SSL
import datetime
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from selenium.webdriver.chrome.options import Options
# 发邮件 msg_to:接收者邮箱
def send(msg_to):
# 我用的是MIMEMultipart的模式,所以可以在邮件里夹图片。
subject = "python+linux测试" # 主题
msg = MIMEMultipart('related')
content = MIMEText('<html><body><h2>测试linux打卡。</h2></body></html>', 'html', 'utf-8') # 正文
# msg = MIMEText(content)
msg.attach(content)
msg['Subject'] = subject
# 发送者邮箱
msg['From'] = "869@qq.com"
msg['To'] = msg_to
try:
s = smtplib.SMTP_SSL("smtp.qq.com", 465) # 邮件服务器及端口号
s.login("869@qq.com", "xxxxxxxxxxxxxxxx") # xxxxx是邮箱的校验码,不是邮箱密码,需在qq邮箱网页内自行获取。
s.sendmail("869@qq.com", msg_to, msg.as_string())
print("发送成功")
except:
print("发送失败")
finally:
s.quit()
# 用户类,保存用户在打卡页面的账号和密码,及通知邮箱地址。
class Person:
schoolNum="180xxxxxx"
psw="iampassword"
email="123456@163.com"
def __init__(self,schoolNum,psw,email):
self.schoolNum = schoolNum
self.psw = psw
self.email = email
# 新建person数组存放Person对象
person=[]
person.append(Person('schoolnumber','thisispassword','herMailAddress@qq.com'))
person.append(Person('schoolnumber','password','hisMailAddress@163.com'))
# 遍历所有用户,模拟打卡操作
for per in person:
# 因为在linux命令行里运行,所以设置无头模式在后台运行。
chrome_options = Options()
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--headless')
# 模拟iPhone 6,因为这个页面如果不是手机端进入的话会进入管理端。
chrome_options.add_argument('user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1"')
#创建对象
driver = webdriver.Chrome(options=chrome_options)
sleep(10)
#进入网站 这里填打卡网站
driver.get(
'http://xgfx.bnuz.edu.cn/xsdtfw/sys/emapfunauth/pages/welcome.do?service=%2Fxsdtfw%2Fsys%2Fswmxsyqxxsjapp%2F*default%2Findex.do%3FwxType%3D1')
# #登录
# 我写了很多sleep,主要是防止网速太慢的时候,dom还没来得及渲染时,selenuim去进行点击等操作的时候会找不到目标元素,就会抛出错误。
sleep(10)
# 点击db认证
driver.find_element_by_xpath('/html/body/div/div/div/div/div/button[2]').click()
sleep(10)
# 这里填账号
driver.find_elements_by_xpath('//input[@class="ivu-input ivu-input-large ivu-input-with-prefix"]')[0].send_keys(
per.schoolNum) # 这里填密码
driver.find_elements_by_xpath('//input[@class="ivu-input ivu-input-large ivu-input-with-prefix"]')[1].send_keys(
per.psw)
# 点击登陆
driver.find_element_by_xpath('//button[@class="ivu-btn ivu-btn-primary ivu-btn-long ivu-btn-large"]').click()
# 点击每日报平安
sleep(10)
driver.find_element_by_xpath('//*[@id="app"]/div/div[2]/a[2]').click()
sleep(10)
# 点击输入体温
driver.find_element_by_xpath(
'//*[@id="app"]/div/div[5]/div/div/div/div/div[7]/div/a/div[2]/div[2]/input').send_keys("37")
sleep(10)
# 点击目前详细地址 有session不用填
# driver.find_element_by_xpath('//*[@id="app"]/div/div[5]/div/div/div/div/div[9]/div/a/div[2]/div[2]/div[1]/textarea').send_keys("金凤路18号")
# 点击本人是否不适
driver.find_element_by_xpath('//*[@id="app"]/div/div[5]/div/div/div/div/div[10]/div/a').click()
sleep(10)
# 点击否
driver.find_element_by_xpath(
'//*[@id="app"]/div/div[5]/div/div/div/div/div[10]/div/div/div[1]/div/div/div/a[2]/div[2]/div[1]/label/span[2]').click()
# 点击本人家属是否接触史
driver.find_element_by_xpath('//*[@id="app"]/div/div[5]/div/div/div/div/div[12]/div/a').click()
sleep(10)
# 点击否
driver.find_element_by_xpath(
'//*[@id="app"]/div/div[5]/div/div/div/div/div[12]/div/div/div[1]/div/div/div/a[2]/div[2]/div[1]/label').click()
# 点击本人家属是否疑似接触过
driver.find_element_by_xpath('//*[@id="app"]/div/div[5]/div/div/div/div/div[14]/div/a').click()
sleep(10)
# 点击否
driver.find_element_by_xpath(
'//*[@id="app"]/div/div[5]/div/div/div/div/div[14]/div/div/div[1]/div/div/div/a[2]/div[2]/div[1]/label').click()
# 点击本人家属是不是疑似病例
driver.find_element_by_xpath('//*[@id="app"]/div/div[5]/div/div/div/div/div[16]/div/a').click()
sleep(10)
# 点击否
driver.find_element_by_xpath(
'//*[@id="app"]/div/div[5]/div/div/div/div/div[16]/div/div/div[1]/div/div/div/a[2]/div[2]/div[1]/label').click()
# 点击本人家属是否被隔离
driver.find_element_by_xpath('//*[@id="app"]/div/div[5]/div/div/div/div/div[18]/div/a').click()
sleep(1)
# 点击否
driver.find_element_by_xpath(
'//*[@id="app"]/div/div[5]/div/div/div/div/div[18]/div/div/div[1]/div/div/div/a[2]/div[2]/div[1]/label').click()
sleep(1)
# 点击提交
driver.find_element_by_xpath('//*[@id="app"]/div/div[6]/div/button').click()
sleep(10)
# 确认一下提交成功没有
# 截图可以放进邮件里
# driver.save_screenshot('./ch.png')
#发送邮件通知
send(per.email)
driver.quit()
linux布置定时任务
代码完成后就可以在服务器上布置定时任务定时运行了。这里用到的是crontab。
假设代码名称:python_bnuz.py
,地址: /root/
命令行输入:vim /etc/crontab
我设定的规则是每日0:10执行语句:
python /root/python_bnuz.py
结果展示
打卡状态通知:
如果没收到邮件的话即是没有打卡成功。
这个时候你可以查看crontab的日志看看是否正常执行。
查看crontab日志语句:tail -f /var/log/cron
结语
感谢你能看到这里呀。这次实践非常有趣,我也学习了很多之前没接触到的新知识。打代码的快乐就在于学后能应用于实际场景吧。自动打卡替我省去了很多麻烦,希望这篇文章也能帮助到你。