init
This commit is contained in:
commit
f303dcb755
35
README.md
Normal file
35
README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# 挂柯南
|
||||
|
||||
## 服务器配置
|
||||
```js
|
||||
// 安装venv
|
||||
python3 -m venv venv
|
||||
// 启动venv
|
||||
. venv/bin/activate
|
||||
// 升级pip
|
||||
pip install --upgrade pip
|
||||
// 安装flask...
|
||||
pip install Flask
|
||||
pip install requests
|
||||
pip install bs4
|
||||
pip install gunicorn
|
||||
// 设置全局变量
|
||||
export FLASK_APP=cust.py
|
||||
export FLASK_ENV=development
|
||||
// 启动临时服务
|
||||
flask run --host=0.0.0.0 -p 5003
|
||||
// 启动永久服务
|
||||
gunicorn cust:app -c gunicorn.conf
|
||||
// 查看已启动服务
|
||||
pstree -ap|grep gunicorn
|
||||
// 关闭某服务
|
||||
kill (pid)
|
||||
```
|
||||
|
||||
## 错误代码一览
|
||||
|
||||
/login
|
||||
100:数据校验失败
|
||||
101:账户错误
|
||||
102:教务挂了
|
||||
200:ok
|
18
cust.py
Normal file
18
cust.py
Normal file
@ -0,0 +1,18 @@
|
||||
# 引入文件夹中的文件
|
||||
import sys
|
||||
sys.path.append('./lib')
|
||||
from allFunction import manageLogin
|
||||
|
||||
from flask import Flask, request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run()
|
||||
|
||||
# 登录接口,前端提供cid和pwd,包装在data里边然后md5校验也就是data:{cid,pwd,sign}
|
||||
@app.route('/api/login',methods=['POST'])
|
||||
def login():
|
||||
res = manageLogin(request)
|
||||
print(res)
|
||||
return res
|
13
gunicorn.conf
Normal file
13
gunicorn.conf
Normal file
@ -0,0 +1,13 @@
|
||||
# 并行工作线程数
|
||||
workers = 4
|
||||
# 监听内网端口5000【按需要更改】
|
||||
bind = '127.0.0.1:5003'
|
||||
# 设置守护进程【关闭连接时,程序仍在运行】
|
||||
daemon = True
|
||||
# 设置超时时间120s,默认为30s。按自己的需求进行设置
|
||||
timeout = 120
|
||||
# 设置访问日志和错误信息日志路径
|
||||
accesslog = './logs/acess.log'
|
||||
errorlog = './logs/error.log'
|
||||
#自动重启
|
||||
autostart = True
|
45
lib/allFunction.py
Normal file
45
lib/allFunction.py
Normal file
@ -0,0 +1,45 @@
|
||||
from crawler import connection, getGrade, getTimetable
|
||||
import json
|
||||
# 主函数
|
||||
|
||||
# 处理登录操作 data:{cid,pwd,sign}
|
||||
# 这里三个接口公用一个session所以合并成一个接口,一个session走到底,一次性返回所有数据
|
||||
def manageLogin(request):
|
||||
# josn化,应该能当dist用
|
||||
data_cache = json.loads(request.form['data'])
|
||||
# MD5校验
|
||||
checked = checkData(data_cache)
|
||||
if checked:
|
||||
# 创建会话
|
||||
res = connect(data_cache)
|
||||
if res['errcode'] == 200:
|
||||
# 登录成功并进行查询
|
||||
grade = getGrade(res['ip'], res['s'])
|
||||
time_table = getTimetable(res['ip'], res['s'])
|
||||
return {'errcode': '200', 'errmsg': 'ok', 'grade': grade, 'time_table': time_table}
|
||||
else:
|
||||
return res
|
||||
else:
|
||||
return {'errcode': 100, 'errmsg':'数据校验失败'}
|
||||
|
||||
|
||||
# 工具函数
|
||||
|
||||
# MD5 校验
|
||||
def checkData(data):
|
||||
return True
|
||||
|
||||
# 创建会话
|
||||
def connect(data):
|
||||
# 用户id 2017....
|
||||
cid = data['cid']
|
||||
# 用户密码
|
||||
pwd = data['pwd']
|
||||
# 进行登录
|
||||
try:
|
||||
# 这里教务没问题,账户没问题就是200,密码错了就是101
|
||||
res = connection(cid,pwd)
|
||||
return res
|
||||
except:
|
||||
# 这了就是教务挂了
|
||||
return {'errcode': 102, 'errmsg':'教务挂了'}
|
71
lib/crawler.py
Normal file
71
lib/crawler.py
Normal file
@ -0,0 +1,71 @@
|
||||
import json
|
||||
import requests
|
||||
from urllib.parse import quote
|
||||
import base64
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
def connection(username,password):
|
||||
s = requests.Session()
|
||||
# 获取统一身份系统的网页
|
||||
r = s.get(url='http://mysso-cust-edu-cn-s.webvpn.cust.edu.cn:8118/cas/login?service=https%3A%2F%2Fwebvpn.cust.edu.cn%2Fauth%2Fcas_validate%3Fentry_id%3D1')
|
||||
soup = BeautifulSoup(r.text,'lxml')
|
||||
execution=soup.find_all(name='input')[6]['value']
|
||||
formdata={
|
||||
'username':username,
|
||||
'password':password,
|
||||
'execution':execution,
|
||||
'_eventId':'submit',
|
||||
'geolocation':''
|
||||
}
|
||||
r = s.post(url='http://mysso-cust-edu-cn-s.webvpn.cust.edu.cn:8118/cas/login?service=https%3A%2F%2Fwebvpn.cust.edu.cn%2Fauth%2Fcas_validate%3Fentry_id%3D1',data=formdata)
|
||||
r = s.get(url='http://portal-cust-edu-cn-s.webvpn.cust.edu.cn:8118/custp/index')
|
||||
soup=BeautifulSoup(r.text,'html.parser')
|
||||
try:
|
||||
ip = soup.findAll(name='a')[6]['href'][7:].split("-")
|
||||
except:
|
||||
return {'errcode': 101, 'errmsg':'账号或者密码错误'}
|
||||
r = s.get(url='http://mysso-cust-edu-cn-s.webvpn.cust.edu.cn:8118/cas/login?service=http://'+ip[0]+'.'+ip[1]+'.'+ip[2]+'.'+ip[3]+':8080/welcome',allow_redirects=False)
|
||||
ticket = r.headers['Location'][68:]
|
||||
asp_net_sessionid_param = {'Ticket':ticket,'Url':'http://'+ip[0]+'.'+ip[1]+'.'+ip[2]+'.'+ip[3]+':8080/welcome'}
|
||||
asp_net_sessionid_param = base64.b64encode(quote(json.dumps(asp_net_sessionid_param)).encode('utf-8')).decode('utf-8')
|
||||
asp_net_sessionid_param = {'param':asp_net_sessionid_param}
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
r = s.post(url='http://'+ip[0]+'-'+ip[1]+'-'+ip[2]+'-'+ip[3]+'-8080-p.webvpn.cust.edu.cn:8118/api/LoginApi/LGSSOLocalLogin?sf_request_type=ajax',data=json.dumps(asp_net_sessionid_param),headers=headers)
|
||||
return {'errcode': 200, 'errmsg': 'ok', 'ip': ip, 's': s}
|
||||
|
||||
def getGrade(Ip, S):
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
r = S.post(
|
||||
url='http://'+Ip[0]+'-'+Ip[1]+'-'+Ip[2]+'-'+Ip[3]+'-8080-p.webvpn.cust.edu.cn:8118/api/ClientStudent/QueryService/GradeQueryApi/GetDataByStudent?sf_request_type=ajax',
|
||||
data=json.dumps({"param":"JTdCJTIyU2hvd0dyYWRlVHlwZSUyMiUzQTElN0Q=","__permission":{"MenuID":"4443798E-EB6E-4D88-BFBD-BB0A76FF6BD5","Operation":0},"__log":{"MenuID":"4443798E-EB6E-4D88-BFBD-BB0A76FF6BD5","Logtype":6,"Context":"查询"}}),
|
||||
headers=headers
|
||||
)
|
||||
data = json.loads(r.content.decode('utf-8'))
|
||||
if data['state'] != 0:
|
||||
return {'errcode': 102, 'errmsg': '教务挂了'}
|
||||
data_cache = []
|
||||
for item in data['data']['GradeList']:
|
||||
data_cache.append(item['LessonInfo']['KCMC']+':'+item['ShowYXCJ'])
|
||||
return {'errcode': 200, 'errmsg': 'ok', 'data': data_cache}
|
||||
|
||||
def getTimetable(Ip, S):
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
r = S.post(
|
||||
url='http://'+Ip[0]+'-'+Ip[1]+'-'+Ip[2]+'-'+Ip[3]+'-8080-p.webvpn.cust.edu.cn:8118/api/ClientStudent/Home/StudentHomeApi/QueryStudentScheduleData?sf_request_type=ajax',
|
||||
data=json.dumps({"param":"JTdCJTdE","__permission":{"MenuID":"F71C97D5-D3E2-4FDA-9209-D7FA8626390E","Operation":0},"__log":{"MenuID":"F71C97D5-D3E2-4FDA-9209-D7FA8626390E","Logtype":6,"Context":"查询"}}),
|
||||
headers=headers
|
||||
)
|
||||
data = json.loads(r.content.decode('utf-8'))
|
||||
if data['state'] != 0:
|
||||
return {'errcode': 102, 'errmsg':'教务挂了'}
|
||||
time = ['AM__TimePieces','PM__TimePieces','EV__TimePieces']
|
||||
data = data['data']['AdjustDays']
|
||||
data_cache = [[0] * 7 for _ in range(6)]
|
||||
for i in range(7):
|
||||
for j in range(3):
|
||||
for k in range(2):
|
||||
if( data[i][time[j]][k]['Dtos'] ):
|
||||
data_cache[j*2+k][i] = []
|
||||
for l in range(4):
|
||||
data_cache[j*2+k][i].append(data[i][time[j]][k]['Dtos'][0]['Content'][l]['Name'])
|
||||
return {'errcode': 200, 'errmsg': 'ok', 'data': data_cache}
|
Loading…
x
Reference in New Issue
Block a user