[Python] 超简单的 超星学习通自动签到

概述

今天两节课的签到都错过了 /(ㄒoㄒ)/~~
所以决定花点时间做一个自动签到的工具
经过观察发现超星的结构很简单,全都是get请求
目标是,能稳定的长时间在线,每隔一段时间就遍历一次列表中的课程,检查是否有签到,签到成功之后发送邮件通知我
之前维护代理IP的数据库的代码已经稳定工作两个星期了 开心o( ̄▽ ̄)ブ

代码

# -*- coding: utf-8 -*
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
import requests as rq
import re
import time
import os

name = "xxxx";    # 学号
pwd = "xxxx";    # 密码
schoolid = "xxx";  #学校id
UA = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'}
cookie = "";

#所有的课程列表 这个是进入课程 点击任务之后 url中的一部分 懒得分离了 直接放在这里了
course_list=[
"courseId=206282287&jclassId=12510333",
"courseId=210417835&jclassId=21309835",
"courseId=206867449&jclassId=18308658"
]

#邮件提醒
def sendMail2(recv_mail,title,content):
    msg_from = 'xxxxx@163.com'  # 发送方邮箱
    passwd = 'xxxx'  # 填入发送方邮箱的授权码(填入自己的授权码,相当于邮箱密码)
    msg_to = [recv_mail]  # 收件人邮箱
    msg = MIMEText(content,'plain', 'utf-8')
    msg['Subject'] = title
    msg['From'] = formataddr(["选课提醒助手", msg_from])
    msg['To'] = recv_mail
    try:
        s = smtplib.SMTP_SSL("smtp.163.com", 465)
        s.login(msg_from, passwd)
        s.sendmail(msg_from, msg_to, msg.as_string())
        print('邮件发送成功')
    except s.SMTPException as e:
        print(e)
        wirte2file(str(e))
    finally:
        s.quit()

def stlog(msg):
    print(msg)
    with open("log.txt","a") as f:
        time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime());
        f.write(time_str+" "+str(msg)+"\n")

def getHtml(url,headers):   #获取网页独立开来方便做异常处理
    try:
        r = rq.get(url,headers=headers,timeout=10)
        return r
    except Exception as e:
        stlog(e)

def login():
    global cookie
    stlog("登录成功")
    url = "http://passport2.chaoxing.com/api/login?name="+name+"&pwd="+pwd+"&schoolid="+schoolid+"&verify=0"
    r = getHtml(url,headers=UA)
    cookie = r.headers["Set-Cookie"]

def getActionID(html,course):
    if len(html) == 0:
        return 
    res = re.findall("activeDetail\(.*.,2,null\)",html)
    if len(res) == 0:   #没有ID的时候 表示可能是cookie过期了
        login()                     #重新登录
    for a in res:
        signIn(a[13:-8],course)

# 获取所有课程的任务界面
def openTask():
    global cookie
    headers = {}
    headers.update(UA)
    headers.update({"cookie":cookie})
    for course in course_list:
        r = getHtml("https://mobilelearn.chaoxing.com/widget/pcpick/stu/index?"+course,headers=headers);
        if r == None:
            return 
        getActionID(r.text,course)

def signIn(activeId,course):
    if os.path.exists("id.txt"):
        with open("id.txt",'r') as f:
            ids = f.readlines()
        if activeId+"\n" in ids:
            return 
    url = "https://mobilelearn.chaoxing.com/widget/sign/pcStuSignController/preSign?activeId="+str(activeId)+"&"+course
    headers = {}
    headers.update(UA)
    headers.update({"cookie":cookie})
    res = getHtml(url,headers=headers)
    res = res.text
    if "qd_Success" in res:   #断言
        with open("id.txt",'a') as f:
            #sendMail2("xxxxxxx@qq.com","签到成功",res)
            stlog(str(activeId)+"签到成功")
            f.write(str(activeId)+"\n")
    else:
        stlog("可能失败了")
        stlog(res)
    time.sleep(1)
    
count = 0;
while True:
    openTask()
    count+=1
    stlog("----------"+str(count)+"-----------")
    time.sleep(100)

其他的

我是windows编写的代码 但是放到linux服务器上面跑的时候遇到了几个问题

文件编码问题

中文注释linux不能正确识别
最前面加
# -*- coding: utf-8 -*

windows 和 linux下换行符不同的问题


上面 后面带^M的是windows的换行符在linux中vim的显示,,, 这样的问题就造成,我判断一个签到是否有被签到的时候会对比错误
需要注意 如果看不懂代码 请不要直接运行上面代码 仅供参考,因为目标网页随时可能发生变化

参考
https://www.z2blog.com/index.php/learn/423.html

posted @ 2020-03-24 01:27  Startu  阅读(14122)  评论(0编辑  收藏  举报