Loading...
墨滴

傲天居士

2021/08/15  阅读:83  主题:默认主题

腾讯云实现网课自动签到

1. 学习通自动签到的需求与分析

疫情期间大家也在认真上网课。网课通常需要签到,并以此作为课程考核标准。很多时候大家也在认真听课,但是总会因为特殊原因忘记签到,造成考核不过关。因此考虑编写一个脚本实现学习通自动签到。

使用Python实现学习通自动签到首先需要登陆网页,登陆函数代码如下:

import requests
requests.packages.urllib3.disable_warnings()

s = requests.Session()
s.headers.update({'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36'})
activates = []

def login():
    global uid,username,password
    if(username == "" or password == ""):
        username = input("登录账号:")
        password = input("登录密码:")
    #旧接口,已失效
    #url="http://i.chaoxing.com/vlogin?passWord="+str(password)+"&userName="+str(username)
    url = f'https://passport2-api.chaoxing.com/v11/loginregister?uname='+str(username)+'&code='+str(password)
    res= s.get(url)
    if("验证通过" in str(res.text)):
        print('Login success!')
        for key, value in res.cookies.items():
            if key=="_uid":
                uid=value
        return s
    else:
        print(username,password)
        print('账号密码有误,请重试。')
        username = ""
        password = ""
        login()

获取用户信息的函数代码如下:

import requests
requests.packages.urllib3.disable_warnings()
from lxml import etree
from urllib.parse import urlparse, parse_qs

s = requests.Session()
s.headers.update({'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36'})
activates = []

def getuserdata():
    web = s.get('http://mooc1-1.chaoxing.com/visit/courses')
    h1 = etree.HTML(web.text)
    name = h1.xpath('//h3[@class = "clearfix"]/a/text()')
    print("-----------课程名称-----------")
    print(name)
    print("------------------------------")
    global count
    try:
        count
    except NameError:
        count_exist = False
    else:
        count_exist = True
    if(count_exist):
        pass
    else:
        if(len(name) == 1):
            count = 0
        else:
            #count = 0
            count = int(input("请用数字选择要签到的课程(从0开始):"))
    geturl = h1.xpath('//div[@class = "Mcon1img httpsClass"]/a/@href')
    i = 0
    courseurl = []
    for temp in range(0,len(geturl)):
        if("/mycourse/studentcourse" in geturl[i]):
            courseurl.append(geturl[i])
        i += 1
    url = 'https://mooc1-1.chaoxing.com' + courseurl[count]
    url_query = urlparse(url).query
    userdata = dict([(k, v[0]) for k, v in parse_qs(url_query).items()])
    global courseId, classId
    courseId = userdata["courseId"]
    classId = userdata["clazzid"]

执行签到的函数代码如下:

import requests
requests.packages.urllib3.disable_warnings()

sckey = ""      #Server酱推送提醒key

s = requests.Session()
s.headers.update({'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36'})
activates = []

def sign(aid, uid):
    global activates
    url = "https://mobilelearn.chaoxing.com/pptSign/stuSignajax?activeId=" + aid + "&uid=" + uid + "&clientip=&latitude=-1&longitude=-1&appType=15&fid=0"
    res = s.get(url,verify=False)
    if (res.text == "success"):
        print(" 签到成功!")
        if sckey != "":
            data = {
                "text" : "签到成功",
                "desp" : "aid" + str(aid)
                }
            sckeyurl = "http://sc.ftqq.com/"+str(sckey)+".send"
            web = s.post(sckeyurl, data=data, verify=False)
        activates.append(aid)
    elif(res.text == "您已签到过了"):
        print(res.text)
        activates.append(aid)
    else:
        if sckey != "":
            data = {
                "text" : "签到失败",
                "desp" : "aid" + str(aid)
                }
            sckeyurl = "http://sc.ftqq.com/"+str(sckey)+".send"
            web = s.post(sckeyurl, data=data, verify=False)
        print("签到失败")

2. 学习通自动签到的Python脚本

有了上述分析与自定义函数,我们不难着手自动签到脚本的编写。完整的Python代码如下:

import requests,time,json
requests.packages.urllib3.disable_warnings()
from lxml import etree
from urllib.parse import urlparse, parse_qs

username = ""   #登录账号
password = ""   #登录密码
sckey = ""      #Server酱推送提醒key

s = requests.Session()
s.headers.update({'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36'})
activates = []

def sign(aid, uid):
    global activates
    url = "https://mobilelearn.chaoxing.com/pptSign/stuSignajax?activeId=" + aid + "&uid=" + uid + "&clientip=&latitude=-1&longitude=-1&appType=15&fid=0"
    res = s.get(url,verify=False)
    if (res.text == "success"):
        print(" 签到成功!")
        if sckey != "":
            data = {
                "text" : "签到成功",
                "desp" : "aid" + str(aid)
                }
            sckeyurl = "http://sc.ftqq.com/"+str(sckey)+".send"
            web = s.post(sckeyurl, data=data, verify=False)
        activates.append(aid)
    elif(res.text == "您已签到过了"):
        print(res.text)
        activates.append(aid)
    else:
        if sckey != "":
            data = {
                "text" : "签到失败",
                "desp" : "aid" + str(aid)
                }
            sckeyurl = "http://sc.ftqq.com/"+str(sckey)+".send"
            web = s.post(sckeyurl, data=data, verify=False)
        print("签到失败")



def login():
    global uid,username,password
    if(username == "" or password == ""):
        username = input("登录账号:")
        password = input("登录密码:")
    #旧接口,已失效
    #url="http://i.chaoxing.com/vlogin?passWord="+str(password)+"&userName="+str(username)
    url = f'https://passport2-api.chaoxing.com/v11/loginregister?uname='+str(username)+'&code='+str(password)
    res= s.get(url)
    if("验证通过" in str(res.text)):
        print('Login success!')
        for key, value in res.cookies.items():
            if key=="_uid":
                uid=value
        return s
    else:
        print(username,password)
        print('账号密码有误,请重试。')
        username = ""
        password = ""
        login()




def getuserdata():
    web = s.get('http://mooc1-1.chaoxing.com/visit/courses')
    h1 = etree.HTML(web.text)
    name = h1.xpath('//h3[@class = "clearfix"]/a/text()')
    print("-----------课程名称-----------")
    print(name)
    print("------------------------------")
    global count
    try:
        count
    except NameError:
        count_exist = False
    else:
        count_exist = True
    if(count_exist):
        pass
    else:
        if(len(name) == 1):
            count = 0
        else:
            #count = 0
            count = int(input("请用数字选择要签到的课程(从0开始):"))
    geturl = h1.xpath('//div[@class = "Mcon1img httpsClass"]/a/@href')
    i = 0
    courseurl = []
    for temp in range(0,len(geturl)):
        if("/mycourse/studentcourse" in geturl[i]):
            courseurl.append(geturl[i])
        i += 1
    url = 'https://mooc1-1.chaoxing.com' + courseurl[count]
    url_query = urlparse(url).query
    userdata = dict([(k, v[0]) for k, v in parse_qs(url_query).items()])
    global courseId, classId
    courseId = userdata["courseId"]
    classId = userdata["clazzid"]

def main():
    getuserdata()
    while 1:
        url = f'https://mobilelearn.chaoxing.com/ppt/activeAPI/taskactivelist?courseId='+courseId+'&classId='+classId+'&uid='+str(uid)
        web = s.get(url,verify=False)
        activeList = json.loads(web.text)["activeList"]
        for item in activeList:
            if ("nameTwo" not in item):
                continue
            if (item['activeType'] == 2 and item['status'] == 1):
                signurl = item['url']
                var = signurl.split("&")
                for var1 in var:
                    var2 = var1.split("=")
                    if(var2[0] == "activePrimaryId"):
                        aid = var2[1]
                if (aid not in activates):
                    print("查询到签到 名称:%s 活动时间:%s aid:%s" % (
                        item['nameOne'], item['nameFour'], aid))
                    sign(aid, uid)
            else:
                time.sleep(3)
                print("签到暂未开通")    

if __name__ == "__main__":
    print("登录成功后等待签到开始")
    try:
        #captchalogin(username,password)
        login()
        main()
    except Exception as e:
        print('repr(e):', repr(e))

用户只需要输入自己的学习通登陆账号与密码即可(分别将登陆账号和登陆密码填入代码username = "" #登录账号password = "" #登录密码)。这里采用了server酱。server酱是一款程序员和服务器之间的通信软件,它可以用于提醒是否签到成功。用户首先需要在浏览器打开网址:https://sct.ftqq.com/upgrade?fr=sc,使用微信扫码登陆即可获取SendKey,然后将填入代码sckey = "" #Server酱推送提醒key,就可以将签到信息推送到微信消息。

3. 腾讯云部署函数

然而每次都要启动Python脚本也很麻烦,往往大家会发现“启动IDE-执行Python脚本-签到成功”的工作流程也很繁琐,有这个时间直接自己手动签到不香吗?这时候就可以将代码部署到腾讯云。用户打开腾讯元进入控制台,新建函数。创建方式选择自定义创建,函数类型选择事件函数,函数名称随意(当然要符号命名规则),部署方式选择代码部署,运行环境选择Python3.6,提交方法选择在线编辑,然后将代码粘贴进去。不要忘记设置触发器,选择定时触发并自定义触发周期。在Cron表达式中进行输入。不理解Cron表达式的可以点击下图的链接: 随后跳出弹窗,即可查阅帮助文档: 根据帮助文档,我们很容易明白。比如对于每周五上午8:00的课程,我们只需要输入表达式“0 0 8 ** 5 *” 即可。当然,如果这位老师提前10分钟上课,并在8:00之前关闭了签到系统,这种方法就会造成漏签。解决办法是设置触发周期为每5分钟,这样每5分钟的0秒就会执行一次函数,从而规避了绝大多数风险。(还不放心可以设置触发周期为每一分钟,不过一般情况每5分钟就足够了)

至此,腾讯云+Python实现学习通自动签到的工作就完成了。由于函数部署在腾讯云,因此电脑是否打开、是否联网都不影响自动签到的执行。

傲天居士

2021/08/15  阅读:83  主题:默认主题

作者介绍

傲天居士