因为疫情的反复,导致我们又一次上起了网课,但这样上课的效率实在太低,我一般都是挂着腾讯课堂然后边打游戏边上课的,这样又造成一个问题,每次上课前都得等着签到,下课还得切回腾讯课堂去签到,甚至中途老师还会偷偷签到,再加上我实在不想上课,做一个脚本就显得非常有必要了。
起因
老师其实也给了我做这个脚本的一个小小动力,那天依旧正常上课,我一般都是提前进教室,本着无聊的心情,和老师聊聊天,老师就问我们是不是有人做了脚本挂课,然后说你们要是能做出来那种脚本也是可以的,说明你们有实力,简直就是一言惊醒梦中人啊,当场我就不玩游戏了,开始研究如何做这个脚本。
2.1版本源代码展示
欸嘿嘿,是的,这个脚本我甚至还做了2.0版本,从270行到100行代码的质变,这其中也经历了很多调试,使用说明文档点击下方按钮传送。
# 运行环境配置
import time
from selenium.webdriver.common.by import By
from selenium.webdriver import Chrome, ChromeOptions
sign_num = 0
class_state = True
option = ChromeOptions()
option.add_argument(r'user-data-dir=C:\Users\CJHONG\AppData\Local\Google\Chrome\User Data')
MyClass = {
# 课程区间
'1': '08:35-10:02',
'2': '10:15-11:42',
'3': '13:55-15:22',
'4': '15:35-17:02',
# 课程链接
'网络设备': 'https://ke.qq.com/webcourse/4358755/104523375#taid=12772399519007331&lite=1',
'网络配置': 'https://ke.qq.com/webcourse/4359424/104524044#taid=12634440874493184&lite=1',
'网络规划': 'https://ke.qq.com/webcourse/4357843/104522463#taid=12702039364763347&lite=1',
'公有应用': 'https://ke.qq.com/webcourse/4359623/104524243#taid=12702975667635655&lite=1',
# 课程表格
'card': {
'Monday': ['1-网络设备', '2-公有应用', '4-网络设备'],
'Tuesday': ['2-网络配置'],
'Wednesday': ['1-公有应用', '2-网络设备', '3-网络规划', '4-网络配置'],
'Thursday': ['1-网络规划', '2-公有应用'],
'Friday': ['2-网络配置'],
}
}
def course(times):
Arr = times.split(sep="-")
now = time.strftime("%H:%M")
return Arr[0] <= now <= Arr[1]
def into(card):
global sign_num
global class_state
ClassArr = []
over = True
for index in range(len(card)):
ClassArr.append(card[index].split(sep="-"))
print("* 欢迎使用DianC自动签到系统 2.1 *")
print("* 已经处于监听状态: ")
while True:
for index in range(len(ClassArr)):
if course(MyClass[ClassArr[index][0]]):
if class_state:
class_state = False
driver = Chrome(options=option)
driver.get(MyClass[ClassArr[index][1]])
print("* 已进入课堂: ")
if driver.find_elements(By.XPATH, '/html/body/div[6]/section'):
print('* ' + str(time.strftime("%A %H:%M:%S")) + ' : 检测到你还未登录! *')
while True:
if not driver.find_elements(By.XPATH, "/html/body/div[6]/section"):
print("* 已登录课堂: ")
break
while True:
sign_info = driver.find_elements(By.XPATH,
'//*[@id="react-body"]/div[3]/div[2]/div/div[3]/span')
select_btn = driver.find_elements(By.XPATH,
'/html/body/div[2]/div[3]/div[2]/div/div[2]/div/div[2]/div/div[1]')
if course(MyClass[ClassArr[index][0]]):
if select_btn:
select_btn[0].click()
driver.find_elements(By.XPATH, '/html/body/div[2]/div[3]/div[2]/div/div[3]/span')[
0].click()
time.sleep(1)
driver.find_elements(By.XPATH, '/html/body/div[2]/div[3]/div[2]/div/div[1]/i')[
0].click()
print("* 检测到答题弹出 -> 答题成功")
sign_num += 1
elif sign_info:
sign_info[0].click()
time.sleep(1)
sign_info[0].click()
print("* 检测到签到弹出 -> 签到成功")
sign_num += 1
else:
time.sleep(2)
continue
else:
print("* 该课程总共签到/答题了: " + str(sign_num) + " 次")
print("* 该课程已结束,正在查询下一节课 *")
driver.close()
sign_num = 0
class_state = True
break
else:
if over:
if course(MyClass[ClassArr[len(ClassArr) - 1][0]].split(sep="-")[1] + '-24:00'):
print("* 今日课程已全部结束 *")
over = False
break
if not over:
break
time.sleep(2)
try:
into(MyClass['card'][time.strftime("%A")])
except:
print("* 系统出现严重错误 ! 请及时反馈管理员: CJHONG *")
其实和1.0最大的区别就是运用了多层循环解决了1.0的elseif过多的问题,同时简化了加课程和时间区间的操作,1.0这里就不放出来了,毕竟太乱了,只能做为2.0的理论基础使用,如果你能看得懂2.0那一定懂1.0。
运行展示
仅供学习参考哈,不建议真的使用这个脚本,还是需要认真上课的 φ( ̄∇ ̄o) 。
以上代码耗时两周,算上1.0的开发时间了,其实逻辑什么的都不算复杂,最难的是获取页面的标签元素,我毕竟不是腾讯课堂的老师(想申请来着,还得认证),不能自己发签到/答题然后进行调试,导致那两天我上课非常认真,一旦老师发起签到/答题,我就立刻F12去看页面的XPATH路径,终于在不断调试的过程中完成了,真的太费心思了,所以这段代码才是被我称为压轴的原因,只可惜没多久就开学了。