方正教务系统做的还挺安全!!! 密码用rsa加密,还带了token防御
一开始,我尝试用 request.post()表单提交数据,没用,看了一下网络请求,表单提交了4个数据,如下图:
也就是说,我们提交给后台的密码是通过rsa加密,把我给整蒙了,然后就继续看网络请求
用fiddler把我眼睛都看疼了,终于找到一个url是这样的: https://jwpd.webvpn.jsei.edu.cn/xtgl/login_getPublicKey.html?time=1654150370993&_=1654150370936
正好是公钥信息,然后我就寻思看看他是怎么加密的,看一下代码文件,果断放弃这个方法。。。,因为我不会,再加上token我也搞不定
下面就到了正题,用selenium模拟登陆,然后再获取想要的信息
大概步骤就是:先设置浏览器一些东西,然后selenium定位文本框位置,填充账号密码信息,登陆,然后url跳转到课表信息,然后用selenium在设置下当前第几周之类的信息,获取到当前周次的课表源码之后,分析一下页面,用bs4或者re慢慢提取到今天的课表信息
完整代码
import math
import time
import datetime
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
import re
from bs4 import BeautifulSoup
# 进入浏览器设置
def webSetting():
global browser
options = webdriver.ChromeOptions()
# 设置中文
options.add_argument('lang=zh_CN.UTF-8')
# 取消下面一行注释设置无头,也就是不显示浏览器了
options.add_argument('--headless')
# 创建浏览器对象
browser = webdriver.Chrome(options=options)
# 规避机器人检测
browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
return browser
# 登陆
# 我们学校的很怪,需要先在今日校园里的页面登陆,然后再到方正的页面登陆一下
#
def login(url,user,pwd):
driver = webSetting()
driver.get(url)
# 表单提交信息
username = driver.find_element(By.ID, 'username')
username.send_keys(user)
password = driver.find_element(By.ID, 'password')
password.send_keys(pwd)
submit = driver.find_element(By.CLASS_NAME, 'auth_login_btn,primary,full_width')
submit.click()
time.sleep(1) # 避免被检测
# 表单提交信息
yhm = driver.find_element(By.ID, 'yhm')
yhm.send_keys(user)
mm = driver.find_element(By.ID, 'mm')
mm.send_keys(pwd)
dl = driver.find_element(By.ID, 'dl')
dl.click()
time.sleep(1)
return driver
# 获取到本周的课表页面源码
def seleniumGetPage(url,user,pwd,week):
driver = login(url,user,pwd)
# 登陆成功,跳转到本周课表页面
driver.get('https://jwpd.webvpn.jsei.edu.cn/kbcx/xskbcxZccx_cxXskbcxIndex.html?gnmkdm=N2154&layout=default&su='+user)
#设置学期和周次信息
selectxqm = driver.find_element(By.ID,'xqm')
Select(selectxqm).select_by_visible_text('2')
selectzs = driver.find_element(By.ID,'zs')
Select(selectzs).select_by_visible_text(str(week))
time.sleep(1)
return driver.page_source
# 查询自己的学期成绩页面源码
def getScore(url,user,pwd):
driver = login(url, user, pwd)
# 登陆成功,跳转到成绩查询页面
driver.get('https://jwpd.webvpn.jsei.edu.cn/cjcx/cjcx_cxDgXscj.html?gnmkdm=N305005&layout=default&su=' + user)
time.sleep(2)
select = driver.find_element(By.NAME, 'currentPage')
Select(select).select_by_visible_text('5000')
search = driver.find_element(By.ID, 'search_go')
# document.getElementById("idName").innerHTML="改变后的内容"
js = 'window.onload=function(){document.getElementById("xnm_chosen")[0].getElementsByClassName ("chosen-single")[0]'
'.getElementsByTagName ("span").innerHTML="全部";}'
selectxnm = driver.find_element(By.ID, 'xnm_chosen')
.find_element(By.CLASS_NAME,'chosen-single').find_element(By.TAG_NAME,'span')
driver.execute_script(js,selectxnm)
#Select(selectxnm).select_by_visible_text('全部')
time.sleep(1)
js1 = 'window.onload=function(){document.getElementById("xqm_chosen")[0].getElementsByClassName ("chosen-single")[0].'
'getElementsByTagName ("span").innerHTML="全部"}'
selectxqm = driver.find_element(By.ID, 'xqm_chosen')
.find_element(By.CLASS_NAME,'chosen-single').find_element(By.TAG_NAME,'span')
#Select(selectxqm).select_by_visible_text('全部')
driver.execute_script(js1,selectxqm)
time.sleep(1)
search.click()
time.sleep(1)
#print(driver.page_source)
# 获取今天是周几
def getToday():
y = datetime.datetime.now().year
m = datetime.datetime.now().month
d = datetime.datetime.now().day
lis = [1,2,3,4,5,6,7,]
dic = dict(enumerate(lis))
w = datetime.date(y,m,d)
return dic[w.weekday()]
#获取当前第几周
def getWeeks(date):
#获取今天日期
y = datetime.datetime.now().year
m = datetime.datetime.now().month
d = datetime.datetime.now().day
today = str(y)+'-'+str(m)+'-'+str(d)
#算出天数
startTime = datetime.datetime.strptime(date,"%Y-%m-%d")
endTime = datetime.datetime.strptime(today, "%Y-%m-%d")
day = (endTime - startTime).days
#算出周次
if(day % 7 == 0):
week = day/7+1
else:
week = math.ceil(day/7)
return int(week)
# 获取当日课表
def getLessonList(r,gt):
# 采用bs4获取元素
soup = BeautifulSoup(r, features="lxml")
tbody = soup.select('#table_tb')
count = 0
# 由于第10节课开始上的课在table中的特殊性,需要计算本周在当天之前有几次是第九节开始上的
for i in range(1, gt):
id = '#' + 'td_' + str(i) + '-9'
if (len(tbody[0].select(id)[0].text) > 0):
count += 1
# 用于存储课程信息
lessonList = []
for info in tbody[0].select('td'):
#元素中id:td_3-1 意思是周三第一节 下同
if (info.get('id') == 'td_' + str(gt) + '-1' and len(info.text) > 0):
lessonList.append(info.text + "(08:30~10:05)")
if (info.get('id') == 'td_' + str(gt) + '-3' and len(info.text) > 0):
lessonList.append(info.text + "(10:20~11:55)")
if (info.get('id') == 'td_' + str(gt) + '-5' and len(info.text) > 0):
lessonList.append(info.text + "(14:00~15:35)")
if (info.get('id') == 'td_' + str(gt) + '-7' and len(info.text) > 0):
lessonList.append(info.text + "(15:50~17:25)")
if (info.get('id') == 'td_' + str(gt) + '-9' and len(info.text) > 0):
lessonList.append(info.text + "(17:30~19:45)")
# 元素中id: td_(gt-count)-10 第十节开始的课特殊性,要减去上面的count
if (info.get('id') == 'td_' + str(gt - count) + '-10' and len(info.text) > 0):
lessonList.append(info.text + "(19:00~20:40)")
return lessonList
# 打印课程信息
def printLesson(r,gt):
List = getLessonList(r, gt)
print("今天一共"+str(len(List))+"节课")
for info in List:
print(info)
if __name__ == '__main__':
timeStr = int(time.time()*1000)
url = 'https://jwpd.webvpn.jsei.edu.cn/xtgl/index_initMenu.html?jsdm=&_t='+str(timeStr)
user = '你的学号'
pwd = '你的密码'
# getScore(url,user,pwd)
# 第一周周一2022-02-14
StartWeek = '2022-02-14'
# 本周周次
week = getWeeks(StartWeek)
# 今天周几
gt = getToday()
# 获取课表页面源码
r = seleniumGetPage(url, user, pwd, week)
# 获取今天的课表信息
printLesson(r,gt)
自己用多个账号测试了一下
同样的道理,选课,查成绩 都应该能通过这样的方法操作



