利用selenium webdrive实现每天自动打卡

疫情期间,学校要求我们每天进行健康打卡,开始时候是老师帮忙一键打卡,可是后来学校却要求每个人每天必须独自打卡,对于忘性大的我来说,每天都要记得打卡实在太过困难,于是准备利用自动打卡,不过卡在了验证码的那一关。然而某天我又去搜索学校的打卡网址的时候发现了有个本校的同学写了类似的程序(参考链接),于是乎就拿来借鉴了一下并加以优化(你懂得😉)

前置配置

Chrome,python,seleinum,webdrive

整体思路

首先利用webdirve获取到网址的验证码,然后登录,登录后跳转到新的界面,利用switch_to_window切换至新的页面,之后通过一系列操作获取到打卡界面网址,最后点击一键打卡,大功告成

优化部分

  1. 由于学校服务器不太行,经常会遇到网页进不去的时候,好在学校好心的帮我们想到了这一点,开通了四个站点,于是加个循环对四个站点分别进行尝试,成功即跳出循环
  2. 原始代码是在跳转页面后再在第一个页面重新加载,虽说也可以实现,不过对于强迫症的我看到与人类操作不符的执行过程实在太过难受,因此优化了切换界面部分
  3. 学校登录网址会在每天九点后会多一个时间的元素,因此初始代码会在九点后获取验证码出现问题,因此把验证码获取的范围加以缩小,使得不会被多出的元素影响到。
  4. 在结尾部分把driver.close()替换成driver.quit(),这样会完全退出浏览器,这个地方在服务器端跑的时候没注意,造成了服务器段开了太多Chrome进程,非常卡顿。

自动执行

完成上述过程后,还是需要自己每天主动去执行一次,实在太过麻烦(人类不就是因为懒惰才会使科技进步的嘛:😜,正巧此时我手上有一台闲置的阿里服务器,所以我决定把它放在阿里的服务器上执行(需要进行一系列配置,此处就不多说了),为了增加真实性,让其每天早上7:00-9:00随机时间执行。

完整代码

主体代码

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
import sys
import selenium.webdriver
import time
import re
from bs4 import BeautifulSoup
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
backupurl=['ispstu','ispstu2','ispstu3','ispstu4']
user=[['用户名'],['密码']]
chrome_options=Options()
# 设置chrome浏览器无界面模式
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
driver = selenium.webdriver.Chrome(options=chrome_options)
for i in range(0,len(user)):
count=0
for j in range(0,4):
try:
url = 'https://xsswzx.cdu.edu.cn/'+backupurl[j]+'/com_user/weblogin.asp'
time.sleep(5)
driver.get(url)
try:
dig_alert=driver.switch_to.alert
dig_alert.accept()
count=count+1
continue
except:
pass
window_1 = driver.current_window_handle #获取当前窗口handle
html = driver.page_source
bs = BeautifulSoup(html,"html.parser")
code = bs.find('div',class_='form-bottom').findAll(name='div')[2].text #获得验证码
s=re.findall('\d+',code)[0]
time.sleep(5)
#输入用户名,密码,验证码
driver.find_element_by_name("username").send_keys(user[i][0])
driver.find_element_by_name("userpwd").send_keys(user[i][1])
driver.find_element_by_name("code").send_keys(s)
driver.find_element_by_name("login").click()
time.sleep(5)
# 切换到最新窗口
windows = driver.window_handles
for current_window in windows:
if current_window != window_1:
driver.switch_to.window(current_window)
time.sleep(5)
try:
driver.switch_to.frame('leftFrame')
html = driver.page_source
bs = BeautifulSoup(html,"html.parser")
url2 = url.rsplit('/',1)[0]+'/'+bs.findAll('a')[43].get('href')
driver.get(url2)
time.sleep(1)
driver.find_element_by_xpath('//input[@value="【一键登记:无变化】"]').click()
dig_alert = driver.switch_to.alert
dig_alert.accept()
print(url)
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),end=' ')
time.sleep(1)
try:
dig_alert = driver.switch_to.alert
dig_alert.accept()
except:
pass
driver.close() #关闭窗口
driver.switch_to.window(window_1) #切换到第一个窗口
print("{0}:登记成功".format(user[i][0]))
break
except:
print("{0}:账号或密码错误".format(user[i][0]))
driver.close()
driver.switch_to.window(window_1)
break
except:
count=count+1
continue
if count>=4:
print("{0}:登记失败".format(user[i][0]))
driver.quit()
sys.exit()

shell代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#! /bin/bash
# 双小括号内可以进行整数运算
randNum=$(($RANDOM%120))
# 大括号防止歧义
sleep ${randNum}m
starttime=`date +'%Y-%m-%d %H:%M:%S'`
echo -e "开始时间:\c" >>result.txt
date "+%Y-%m-%d %H:%M:%S">>result.txt
python /root/register.py >> result.txt
endtime=`date +'%Y-%m-%d %H:%M:%S'`
start_seconds=$(date --date="$starttime" +%s);
end_seconds=$(date --date="$endtime" +%s);
echo "本次运行时间:"$((end_seconds-start_seconds))"s" >> result.txt
echo -e "\n" >>result.txt
-------------本文结束感谢您的阅读-------------