Python实现腾讯课堂自动签到脚本

首页 / 技术积累 / 正文

因为疫情的反复,导致我们又一次上起了网课,但这样上课的效率实在太低,我一般都是挂着腾讯课堂然后边打游戏边上课的,这样又造成一个问题,每次上课前都得等着签到,下课还得切回腾讯课堂去签到,甚至中途老师还会偷偷签到,再加上我实在不想上课,做一个脚本就显得非常有必要了。

起因

老师其实也给了我做这个脚本的一个小小动力,那天依旧正常上课,我一般都是提前进教室,本着无聊的心情,和老师聊聊天,老师就问我们是不是有人做了脚本挂课,然后说你们要是能做出来那种脚本也是可以的,说明你们有实力,简直就是一言惊醒梦中人啊,当场我就不玩游戏了,开始研究如何做这个脚本。

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。

运行展示

1.jpg

仅供学习参考哈,不建议真的使用这个脚本,还是需要认真上课的 φ( ̄∇ ̄o) 。

以上代码耗时两周,算上1.0的开发时间了,其实逻辑什么的都不算复杂,最难的是获取页面的标签元素,我毕竟不是腾讯课堂的老师(想申请来着,还得认证),不能自己发签到/答题然后进行调试,导致那两天我上课非常认真,一旦老师发起签到/答题,我就立刻F12去看页面的XPATH路径,终于在不断调试的过程中完成了,真的太费心思了,所以这段代码才是被我称为压轴的原因,只可惜没多久就开学了。

评论区
头像