[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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM