-
Notifications
You must be signed in to change notification settings - Fork 1
/
cource_selector.py
135 lines (124 loc) · 5.12 KB
/
cource_selector.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# Automated Cource Selection (ACS)
# Created by Cheng Xinlun @Tsinghua University, 2015/09/18
# First draft finished debugging @Tsinghua University, 2015/09/20
# Major improvement @Tsinghua Univerity, 2017/05/15
# Dependencies
# 1. Python 3
# 2. requests, Pillow
# 3. scikit-image (skimage)
# Import necessary modules
import requests
import urls
import ipro
import headers
# Self-defined class for exception
class XKException(Exception):
pass
# Class for class selection
class XuanKe():
def __init__(self, sem, cc, cn, cs, user, pswd):
# Variable initialization
self.semester = sem
self.class_class = cc
self.class_number = cn
self.class_subnumber = cs
self.user = user
self.pswd = pswd
self.gettoken_data = {"m": self.class_class + "Search",
"p_xnxq": self.semester,
"tokenPriFlag": self.class_class, "is_zyrxk": "1"}
self.login_webaddr = urls.urlCook
self.validator = urls.urlVali
self.captcha_addr = urls.urlCapt
self.login_postaddr = urls.urlLogi
self.xkaddr = urls.urlCous
# Generic header
self.gheader = headers.headGene
# Login header construction
self.lheader = headers.headGene
self.lheader.update(headers.headAcce)
self.lheader.update(headers.headCook)
# Login and get captcha
def login(self):
while True:
s = requests.Session()
responce = s.get(self.login_webaddr, headers=self.gheader)
if responce.url != self.login_webaddr:
s.close()
continue
get_check = s.get(self.validator, headers=self.gheader)
if get_check.url != self.validator:
s.close()
continue
captcha_responce = s.get(self.captcha_addr, headers=self.gheader)
if captcha_responce.url != self.captcha_addr:
s.close()
continue
# Get and save captcha into file named with the picture md5
output_captcha = open("temp.jpg", "bw")
output_captcha.write(captcha_responce.content)
output_captcha.close()
# Captcha
captcha = ipro.iip("temp.jpg")
print(captcha)
# Login post data construct
self.login_data = {"j_username": self.user,
"j_password": self.pswd,
"captchaflag": "login1",
"_login_image_": captcha}
login_res = s.post(self.login_postaddr, self.login_data,
headers=self.lheader, verify=False)
if login_res.url != urls.urlCous + "?m=main":
s.close()
continue
break
return s
# Get token for the first time from returned webpage
def gettoken(self, s):
gettoken_res = s.post(self.xkaddr, self.gettoken_data,
headers=self.gheader)
if gettoken_res.url != self.xkaddr:
s.close()
raise XKException("Kicked offline. Relogining...")
token = gettoken_res.text.split(
"<input type=\"hidden\" name=\"token\" value=\"", 2)[1].split(
"\"", 2)[0]
return [s, token]
# Select cource (no search needed which saves a hell lot of time!!)
def selection(self, s, token):
selection_data = {"m": "save" + str.capitalize(self.class_class) + "Kc",
"page": "", "token": token, "p_sort.p1": "",
"p_sort.p2": "", "p_sort.asc1": "true",
"p_sort.asc2": "true", "p_xnxq": self.semester,
"is_zyrxk": "", "tokenPriFlag": self.class_class,
"p_kch": self.class_number, "p_kcm": "",
"p_kkdwnm": "", "p_kctsm": "", "p_rxklxm": "",
"p_rx_id": self.semester + ";" + self.class_number +
";" + self.class_subnumber + ";", "goPageNumber": "1"}
selection_result = s.post(self.xkaddr, selection_data,
headers=self.gheader)
if selection_result.url != self.xkaddr:
s.close()
raise XKException("Kicked offline. Relogining...")
success_or_not = selection_result.text.split("showMsg(\"", 2)[1].split(
"\"", 2)[0]
return success_or_not
# Main process to be called from outside
def main_process(self):
while True:
# Return a processed session from login() function
session = self.login()
try:
[session, token] = self.gettoken(session)
except XKException as reason:
print(str(reason) + "\n")
continue
try:
selection_res = self.selection(session, token)
except XKException as reason:
print(str(reason) + "\n")
continue
# Process return result from selection
print(selection_res + "\n")
session.close()
continue