Skip to content

Instantly share code, notes, and snippets.

@ksqsf
Created January 29, 2018 20:58
Show Gist options
  • Save ksqsf/b1d5e16386ae7d45e3d8f296bcc0df71 to your computer and use it in GitHub Desktop.
Save ksqsf/b1d5e16386ae7d45e3d8f296bcc0df71 to your computer and use it in GitHub Desktop.
USTC Web services
"""
the USTC module
NOTE: this is an incomplete framework! extend it as you like.
PS: don't expect to receive updates or changes from me! this is not intended to be published anyway. :-p
"""
from bs4 import BeautifulSoup
import requests
class Passport:
"""
USTC Passport
1. GET USTC_LOGIN and obtain the CSRF token
2. Construct a form and POST it to USTC_LOGIN
3. Get cookies `laravel_session` and `ucas_TGC_2015`
"""
LOGIN_URL = "https://passport.ustc.edu.cn/login"
def __init__(self, student_id: str, password: str):
# Query a token
res = requests.get(Passport.LOGIN_URL)
cookies = res.cookies
soup = BeautifulSoup(res.text, 'html.parser')
token = soup.form.input['value']
# Login
payload = {'_token': token, 'login': student_id, 'password': password, 'button': '登录'}
res = requests.post(Passport.LOGIN_URL, data=payload, cookies=cookies)
# Save the cookies for future use
self.cookies = res.cookies
# Check if succeeded
if res.text.find('成功') == -1:
raise RuntimeError("Couldn't not log into Passport")
class MIS:
"""
USTC MIS
1. GET USTC_MIS_LOGIN with appropriate cookies
2. Cookie `JSESSIONID` returned
"""
LOGIN_URL = "https://passport.ustc.edu.cn/login?service=http%3A%2F%2Fmis.teach.ustc.edu.cn/casLogin.do"
GRADES_URL = "http://mis.teach.ustc.edu.cn/querycjxx.do"
def __init__(self, passport: Passport):
res = requests.get(MIS.LOGIN_URL, cookies=passport.cookies)
self.cookies = res.cookies
def courses(self, semester: str):
"""
Query courses you selected for a specific semester. Semester is a string in the format
`'XXXXX'`, where `X` is a digit. The first 4 digits stand for the year, and the last digit
stands for the specific semester, which can be 1 (Fall), 2 (Spring) or 3 (Summer).
"""
raise NotImplementedError()
def grades(self):
"""
Query your grades.
Surprisingly, GET request is sufficient. HTML contents (!) are returned, so we must parse
them into machine-readable format, ie. dictionary.
@return as {total_credits, obtained_credits, not_obtained_credits, failed_credits, GPA,
average, weighted_average, [{semester, number, name, type, grade, credits}]}
"""
res = requests.get(MIS.GRADES_URL, cookies=self.cookies)
soup = BeautifulSoup(res.text, 'html.parser')
general_info = soup.tr.find_all()
course_info = soup.find_all('table')[2].find_all('tr')
ret = dict()
ret['total_credits'] = float(general_info[1].text)
ret['obtained_credits'] = float(general_info[3].text)
ret['not_obtained_credits'] = float(general_info[5].text)
ret['failed_credits'] = float(general_info[7].text)
ret['GPA'] = float(general_info[9].text)
ret['average'] = float(general_info[11].text)
ret['weighted_average'] = float(general_info[13].text)
courses = []
for course in course_info[:-1]: # the last line is empty
cols = course.find_all('td')
courses.append({'semester': cols[0].text, 'number': cols[1].text, 'name': cols[2].text,
'type': cols[3].text, 'grade': cols[4].text, 'credits': cols[5].text})
ret['courses'] = courses
return ret
def main():
"Shut up."
passport = Passport('你的学号', '你的密码')
mis = MIS(passport)
print(mis.grades())
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment