首先贴下github项目地址 (如果觉得这个程序好,求个star)

运行该小程序需安装requests和bs4库,还需要安装能操作excel的xlwt库

1
2
3
pip install requests
pip install bs4
pip install xlwt

现在该程序不能自动识别验证码,需手动在控制台输入验证码, 现可免输入验证码即可登陆(需先在github上获取该库,然后使用分支nocode)使用命令即可

1
git checkout nocode

然后输入学号和密码即可查询,作者本人大二,所以现在可支持查询大一两个学期和大二上的成绩,成绩会自动保存在本地。
由于课表不好格式化输出,如需查课表,程序会生成一个excel文件,然后直接查看即可

思路

首先用requests库模拟登陆学校的教务系统,然后再进入成绩查询的页面,得到该页面的html源码,用BeatufulSoup来解析页面,提取出每门课的学分和成绩用列表来储存,最后格式化输出,并将输出写入文件。
我把直接用函数来表示每个步骤,自我感觉思路比较清晰

源码

查分小程序

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
import requests
from bs4 import BeautifulSoup,element
import os

login_url = 'http://run.hbut.edu.cn/Account/LogOn'
checkimg = 'http://run.hbut.edu.cn/Account/GetValidateCode'
StuGrade = 'http://run.hbut.edu.cn/StuGrade/Index'
g_20171 = '?SemesterName=20171&SemesterNameStr=2017学年%20第一学期'
g_20162 = '?SemesterName=20162&SemesterNameStr=2016学年%20第二学期'
g_20161 = '?SemesterName=20161&SemesterNameStr=2016学年%20第一学期'

file = open('grade.txt','w+')
session = requests.Session()
headers = {
'Referer' : 'http://run.hbut.edu.cn/',
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
}

#获取登陆验证码
def GetValidateCode():
checkcodecontent = session.get(checkimg,headers=headers)
with open('checkcode.jpg','wb') as f:
f.write(checkcodecontent.content)
print('验证码已写入到本地!')
os.startfile("checkcode.jpg")
checkcode = input("请输入验证码:")
payload = {
'Role':'Student',
'UserName': input('请输入账号:'),
'Password': input('请输入密码:'),
'ValidateCode': checkcode
}
return payload

#获取课程成绩页面
def getHtmlText(SemesterName,payload):
respose = session.post(login_url,headers=headers,data=payload)
print('服务器端返回码:',respose.status_code)
if SemesterName is '1':
SemesterName = g_20161
if SemesterName is '2':
SemesterName = g_20162
if SemesterName is '3':
SemesterName = g_20171
grade_url = StuGrade+SemesterName
stugrade = session.get(grade_url,headers=headers)
return stugrade.text

#提取各科成绩
def GetFromText(txt):
form = []
soup = BeautifulSoup(txt,'html.parser')
for tr in soup.find('table').children:
try:
if isinstance(tr,element.Tag):
tds = tr('td')
Class = tds[1].string #课程
Credit = tds[4].string #学分
Grade = tds[5].string #成绩
form.append([''.join(Class.split()),''.join(Credit.split()),''.join(Grade.split())])
except:
continue

return form

#格式输出各科成绩
def printgrade(ulist,num):
tplt = "{0:{3}^25}\t{1:^10}\t{2:^10}\n"
print(tplt.format("课程","学分","成绩",chr(12288)))
file.write(tplt.format("课程","学分","成绩",chr(12288)))
for i in range(num):
u = ulist[i]
print(tplt.format(u[0],u[1],u[2],chr(12288)))
file.write(tplt.format(u[0],u[1],u[2],chr(12288)))

def main():
try:
payload = GetValidateCode()
print('16学年第一学期: 1')
print('16学年第二学期: 2')
print('17学年第一学期: 3')
SenesterName = input('请输入查询的学期:')
txt = getHtmlText(SenesterName,payload)
form = GetFromText(txt)
printgrade(form,len(form));
except :
print("Error")
finally:
file.close()

main()

查课小程序

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
import requests
from bs4 import BeautifulSoup
import xlwt
import os

login_url = 'http://run.hbut.edu.cn/Account/LogOn'
checkimg = 'http://run.hbut.edu.cn/Account/GetValidateCode'
Schedule = 'http://run.hbut.edu.cn/ArrangeTask/MyselfSchedule'
workbook = xlwt.Workbook(encoding='utf-8')
worksheet = workbook.add_sheet('MyselfSchedule')
session = requests.Session()
headers = {
'Referer' : 'http://run.hbut.edu.cn/',
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
}

#获取登陆验证码
def GetValidateCode():
checkcodecontent = session.get(checkimg,headers=headers)
with open('checkcode.jpg','wb') as f:
f.write(checkcodecontent.content)
print('验证码已写入到本地!')
os.startfile("checkcode.jpg")
checkcode = input("请输入验证码:")
payload = {
'Role':'Student',
'UserName': input('请输入账号:'),
'Password': input('请输入密码:'),
'ValidateCode': checkcode
}
return payload

#获取课程表网页
def getHtmlText(payload):
respose = session.post(login_url,headers=headers,data=payload)
print('服务器端返回码:',respose.status_code)
work = session.get(Schedule,headers=headers)
return work.text

#提取网页中的课程表
def getFormText(string):
soup = BeautifulSoup(string,'html.parser')
list = []
for tr in soup.find('table').children:
try:
time = tr('th')[0].string
if time==None:
continue
day1 = tr('td')[0].string
day2 = tr('td')[1].string
day3 = tr('td')[2].string
day4 = tr('td')[3].string
day5 = tr('td')[4].string
day6 = tr('td')[5].string
day7 = tr('td')[6].string
list.append([time,day1,day2,day3,day4,day5,day6,day7])
except:
continue
return list

#将提取到的课程表写入excel表格中
def WirteXls(list):
worksheet.write(0,1,"星期一")
worksheet.write(0,2,"星期二")
worksheet.write(0,3,"星期三")
worksheet.write(0,4,"星期四")
worksheet.write(0,5,"星期五")
worksheet.write(0,6,"星期六")
worksheet.write(0,7,"星期日")
for i in range(len(list)):
u = list[i]
for k in range(8):
worksheet.write(i+1,k,u[k])


def main():
try:
payload = GetValidateCode()
string = getHtmlText(payload)
string = string.replace('<br />','')
list = getFormText(string)
WirteXls(list)

finally:
workbook.save('MyselfSchedule.xls')

main()