概述
今天兩節課的簽到都錯過了 /(ㄒ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的顯示,,, 這樣的問題就造成,我判斷一個簽到是否有被簽到的時候會對比錯誤
需要注意 如果看不懂代碼 請不要直接運行上面代碼 僅供參考,因為目標網頁隨時可能發生變化