前言
又到了選課的時間,又一次被教務系統的預選給安排了,硬是一門都沒選中。於是想實現有沒有自動撿課的方法。就整體分為兩種方法,一種是獲取get請求然后由python多線程提交去選課,一種是利用自動化測試的selenium庫去調用谷歌瀏覽器模擬人工選課操作。其實就算都是強智系統,但細節上還是有些差別的。所以也有可能無法實現。這里放出兩種方法的代碼和流程,僅供參考。
方法一:
直接提交選課的數據包(需要cookie和課程ID),先用同學的賬號登錄教務系統,進入到選課的地方,打開瀏覽器的開發模式(按F12),點擊Network()我這里是谷歌瀏覽器,如果是其他的找到網絡抓包即可。
點擊你想選擇課程的選課按鈕,得到我們需要的數據包。
我們來看下這個數據包的內容,我們需要找到cookie( 你的身份標識),以及我們需要選的課程ID,然后用python模擬提交就OK了。
注意 代碼里的User_Agent和Referer也要記得修改,都在數據包里。
下面是代碼:
import requests
from future.backports.test.ssl_servers import threading
# 獲取cookie 和 課程id就可以搶課
def qian1():
data = 201820192001656
# data 是找到的課程ID,因為python沒學好,代碼寫的有點亂
# 下面是地址 就是我們抓到的那個數據包的URL
url = 'http://****(學校的地址).edu.cn/jsxsd/xsxkkc/bxxkOper?jx0404id='+str(data)
cookie = ' 用找到的cookie替換'
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36',
'Referer': 'http://........../srun_portal_pc.php?ac_id=1',
'cookie':cookie
}
# 一直搶!
while True:
# 設定5s服務器未應答就放棄這次,鬼知道是服務器炸了還是。。。。
mes = requests.get(url, headers=header, timeout=5)
# 打印返回的結果,就是彈出來的那個小窗口的內容
print(str(1)+str(mes.status_code)+':'+str(mes.text))
# 后面是不同的課,因為不能吊在一課樹上!
def qian():
data = 201820192001302
url = 'http://*****/jsxsd/xsxkkc/bxxkOper?jx0404id='+str(data)
cookie = '*****cookie'
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36',
'Referer': 'http://172.30.1.70/srun_portal_pc.php?ac_id=1',
'cookie':cookie
}
while True:
mes = requests.get(url, headers=header, timeout=5)
print(str(0)+str(mes.status_code)+':'+str(mes.text))
def qian2():
data = 201820192001155
url = 'http://****n/jsxsd/xsxkkc/bxxkOper?jx0404id=' + str(data)
cookie = 'cookie'
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36',
'Referer': 'http://172.30.1.70/srun_portal_pc.php?ac_id=1',
'cookie': cookie
}
while True:
mes = requests.get(url, headers=header, timeout=5)
print(str(2)+str(mes.status_code) + ':' + str(mes.text))
def main():
# 開多線程分開搶課
# 接下來就會一直搶課!
thread1 = threading.Thread(target=qian)
thread2 = threading.Thread(target=qian1)
thread3 = threading.Thread(target=qian2)
thread4 = threading.Thread(target=qian)
thread5 = threading.Thread(target=qian1)
thread6 = threading.Thread(target=qian2)
thread1.start()
thread2.start()
thread3.start()
thread4.start()
thread5.start()
thread6.start()
main()
方法二:selenium庫模擬人工選課
要使用這個方法之前,最好先看一下這一篇文章,了解如何使用selenium庫。記得提前安裝好selenium庫,以及Chromedriver。具體方法可以在csdn搜索。
使用流程
- 將腳本內信息填好改好
- 運行腳本,此時會打開chrome並且打開登錄頁,腳本會自行填寫學號密碼,需要等你填寫驗證碼
# author: Viper
# time: 2020/7/2 12:03
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
chrome_options = webdriver.ChromeOptions()
class Qiangke(object):
login_url = "https://***.edu.cn/jsxsd/" #登錄頁面,修改成你學校的登錄地址
select_url = "****/jsxsd/xsxk/xsxk_index?jx0502zbid=B563D5935D024C6387445066336AA73B"#修改為登錄成功后的界面
initmy_url = "https://****/jsxsd/framework/xsMain.jsp"
#修改為你選課的界面
xh = u"****" #填寫用戶名
pwd = '****' #填寫密碼
_user = "****@qq.com" #填寫你的郵箱(用於發郵件提醒搶課成功)
_pwd = "****" #授權碼,在郵箱里獲得
_to = "****@qq.com" #收件人郵箱,可以寫自己的,幫別人搶課就發別人的
course_category = u'公選課選課' # 這里填寫選課種類,這個腳本只能搶跨年級,跨專業,和公選,需輸入完整的名字如“專業內跨年級選課”,“跨專業選課”,“公選課選課”
class_name = u"美術賞析" #這里輸入你想搶的課的名字(關鍵字即可)
teacher_name = u"" #這里輸入你想搶的課的老師的名字
def __init__(self):
print("開始搶課")
def login(self):
self.driver.get(self.login_url)
self.driver.find_element_by_id("details-button").click()
self.driver.find_element_by_id("proceed-link").click()
self.driver.find_element_by_name("USERNAME").send_keys(self.xh)
self.driver.find_element_by_name("PASSWORD").send_keys(self.pwd)
print("等待驗證碼,自行輸入....")
while True:
if self.driver.current_url != self.initmy_url:
sleep(1)
else:
break
def send(self, text, send_msg=False):
import smtplib
from email.mime.text import MIMEText
msg = MIMEText(text)
msg["Subject"] = "你選課成功了!"
msg["From"] = self._user
msg["To"] = self._to
s = smtplib.SMTP_SSL("smtp.qq.com", 465)
s.login(self._user, self._pwd)
s.sendmail(self._user, self._to, msg.as_string())
s.quit()
def start(self):
# 這里需要根據自己的教務系統去修改了,有挺多不一樣的地方。所以建議閱讀完使用文檔再來修改
self.driver = webdriver.Chrome(chrome_options=chrome_options)
self.login()
self.driver.get(self.select_url)
self.driver.find_element_by_link_text(self.course_category).click()
self.driver.switch_to.frame(self.driver.find_element_by_xpath('//*[@id="mainFrame"]'))
self.driver.find_element_by_id('kcxx').send_keys(self.class_name)
self.driver.find_element_by_id('skls').send_keys(self.teacher_name)
self.driver.find_element_by_value(u"查詢").click()
cnt = 1
while True:
try:
self.driver.find_element_by_link_text('選課').click()
except:
self.driver.switch_to.default_content()
self.driver.switch_to.frame(self.driver.find_element_by_xpath('//*[@id="mainFrame"]'))
self.driver.find_element_by_link_text("選課").click()
dig_alert = self.driver.switch_to.alert
dig_alert.accept()
text = dig_alert.text
if text != '選課失敗:此課堂選課人數已滿!' and text != '':
self.send('{} 選課成功'.format(self.class_name))
break
elif text == '':
dig_alert.accept()
cnt += 1
if cnt % 200 == 0:
print(cnt)
if __name__ == "__main__":
qiangke = Qiangke()
qiangke.start()