Python实现爬取教务处成绩系统

Python查询教务处成绩系统简介

项目简介:

该项目是利用tornado框架写的,程序运行后,可以在浏览器输入地址进行访问网站,可以实现输入账号密码后查询成绩。以及可以进行评教。

项目工程文件目录:

工程


图:项目工程文件

网页

图:网页文件

程序功能和效果图如下:


登录界面:

登录界面要求输入账号密码,如果账号密码不正确,都会提示错误。

登录

图:登录界面

菜单界面:

菜单界面,实现的功能有,查询本学期成绩,一次性查询历年所有成绩。以及可以进行评教。还可以查询各学习的成绩。

菜单


图:菜单界面

查看本学期成绩:

进入该页面,可以列出本学习需要考试的课程,当成绩出来后,可以显示每门课的成绩信息,点击每门课的标题,还可进一步查看本课程的详细信息。

本学期成绩


图:查看本学期成绩

查看课程详细成绩:

可以查看课程的更详细成绩,最高分,最低分,平均分等。

详细课程信息


图:查看课程详细成绩

查看各学期成绩:

查看各学习的成绩,可以统计各学习的总学分,通过课程数等。

学习成绩


图:查看各学期成绩

评教界面:

分为以评估和待评估列表。可以进行相应的操作。点击代评估课程,可以进行评教。点击已评估课程,可以查看该课程的评教结果。

评教


图:评教界面

Python实现代码

demo.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
import tornado.httpserver
import tornado.web
from tornado.options import options,define
import tornado.ioloop
import os.path
from handler import *
#import pymysql as sql

define("port", default=8899, help="run on give port", type=int)

class Application(tornado.web.Application):
def __init__(self):
#conn = sql.connect(host='localhost', user='root', password='root', port=3306, database='dtxt', charset='utf8')
#self.db = conn
handlers = [
(r'/', Index),
(r'/menu', Menu),
(r'/login', login),
(r'/list', tlist),
(r'/toEval', toEval),
(r'/EvalResult', ResultShow),
(r'/Showbxqcjcx', Showbxqcjcx),
(r'/ShowAllScore', ShowAllScore),
(r'/ShowTermScore', ShowTermScore),
(r'/ShowSubjectScore',ShowSubjectScore),
(r'/SaveAllScore', SaveAllScore)
]

settings = dict(
template_path = os.path.join(os.path.dirname(__file__), "templates"),
static_path = os.path.join(os.path.dirname(__file__), "static"),
debug = True,
autoreload = True,
cookie_secret="feljjfesrh48thfe2qrf3np2zl90bmwj",
xsrf_cookie=True,
)

tornado.web.Application.__init__(self, handlers = handlers, **settings)

if __name__ == "__main__":
tornado.options.parse_command_line()
http_server = tornado.httpserver.HTTPServer(Application())
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()

handler.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
import tornado.web
#import pymysql as sql
import requests
from lxml import etree
from tornado import gen
import time
from urllib import parse
import re
from bs4 import BeautifulSoup

class BaseHandler(tornado.web.RequestHandler):
def get_current_user(self):
user = self.get_secure_cookie('Cookie')
if user:
return user.decode()
else:
self.redirect('/login')
class Index(tornado.web.RequestHandler):
@gen.coroutine
def get(self):
self.redirect('/login')

class Menu(BaseHandler):
@gen.coroutine
def get(self):
uid = self.current_user
#uid = self.current_user
if not uid:
self.redirect('/login')
head = {
'Accept': 'image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*',
'Accept-Language': 'zh-CN',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
'Host': '211.82.47.2',
'Cookie': uid
}
#all_score = requests.get('http://211.82.47.2/gradeLnAllAction.do?type=ln&oper=qbinfo&lnxndm=2016-2017学年秋(两学期)#2016-2017学年秋(两学期)', headers = head)
all_score = requests.get('http://211.82.47.2/gradeLnAllAction.do?type=ln&oper=qbinfo', headers = head)
all_score.close()
scoreSoup = BeautifulSoup(all_score.text, 'html.parser')
term = [] #存放学期
for i in scoreSoup.find_all('a'):
term.append(i['name'])
self.render('menu.html', term = term)

class login(tornado.web.RequestHandler):
@gen.coroutine
def get(self):
self.render("login.html")

@gen.coroutine
def post(self):
zjh = self.get_body_argument('zjh')
mm = self.get_body_argument('mm')
postdata = {
'evalue' : '',
'zjh1' :'',
'zjh' : zjh,
'fs' : '',
'v_yzm' : '',
'lx' : '',
'mm' : mm,
'eflag' : '',
'dzslh' : '',
'tips' : ''
}
head = {
"Accept-Language":"zh-CN,zh;q=0.8",
'Accept':"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36",
"Connection":"keep-alive",
}
res = requests.post('http://211.82.47.2/loginAction.do', data = postdata, headers=head)
res.close()
if len(res.content) < 2000:
cookie = res.headers['Set-Cookie'][:32]
self.set_secure_cookie("Cookie", cookie, expires_days=None, expires=time.time()+500)
self.redirect('/menu')
else:
self.write("账号密码错误")

class tlist(BaseHandler):
@gen.coroutine
def get(self):
uid = self.current_user

if uid:
#self.write('JSESSIONID: %s' % uid)
head = {
"Accept-Language":"zh-CN,zh;q=0.8",
'Accept':"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36",
"Connection":"keep-alive",
"Cookie" : uid
}
two = requests.get('http://211.82.47.2/jxpgXsAction.do?oper=listWj&pageSize=300', headers = head)
notPg = []
hadPg = []
content = etree.HTML(two.text)
for link in content.xpath('//img')[0:-5]:
if link.get('title') == '评估':
notPg.append(link.get('name').split('#@'))
else:
hadPg.append(link.get('name').split('#@'))

"""ret = ''
for i in hadPg:
ret += i
ret += '<br>'
self.write(ret)"""
self.render('teacher_list.html', notPg = notPg, hadPg = hadPg)

class toEval(BaseHandler):
@gen.coroutine
def get(self):
uid = self.current_user
if not uid:
self.redirect('/login')
head = dict()
head['Content-Type'] = 'application/x-www-form-urlencoded'
#head['Referer'] = 'http://211.82.47.2/jxpgXsAction.do'
head['Accept-Language'] = 'zh-CN'
head['Cache-Control'] = 'no-cache'
head['Accept'] = 'text/html,application/xhtml+xml,application/xml'
head['Accept-Encoding'] = 'gzip, deflate'
head['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'
head['Cookie'] = uid

bpr = self.get_argument('bpr')
wjbm = self.get_argument('wjbm')
pgnr = self.get_argument('pgnr')
wj = {
'bpr': bpr,
'bprm': self.get_argument('bprm'),
'wjmc': self.get_argument('wjmc'),
'wjbz': 'null',
'wjbm': wjbm,
'pgnrm': self.get_argument('pgnrm'),
'pgnr': pgnr,
'pageSize': '20',
'pageNo': '',
'page': '1',
'oper': 'wjShow',
'currentPage': '1'
}
wj = parse.urlencode(wj, encoding='gbk').encode()
two = requests.post('http://211.82.47.2/jxpgXsAction.do', data = wj, headers=head)
two.close()
self.render("eval_page.html", bpr = bpr, wjbm = wjbm, pgnr = pgnr)
#self.write(two.text)


@gen.coroutine
def post(self):

uid = self.current_user
if not uid:
self.redirect('/login')
head1 = dict()
head1['Content-Type'] = 'application/x-www-form-urlencoded'
head1['Referer'] = 'http://211.82.47.2/jxpgXsAction.do'
head1['Accept-Language'] = 'zh-CN'
head1['Cache-Control'] = 'no-cache'
head1['Accept'] = 'text/html,application/xhtml+xml,application/xml'
head1['Accept-Encoding'] = 'gzip, deflate'
head1['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'
head1['Cookie'] = uid

one = self.get_body_argument('one')
two = self.get_body_argument('two')
three = self.get_body_argument('three')
four = self.get_body_argument('four')
zero = self.get_body_argument('zero')
data = {
'0000000002': zero,
'0000000003': zero,
'0000000011': one,
'0000000012': one,
'0000000013': three,
'0000000014': three,
'0000000021': four,
'0000000022': three,
'0000000023': one,
'0000000024': two,
'0000000031': three,
'0000000032': two,
'0000000033': three,
'0000000034': three,
'0000000041': zero,
'0000000042': zero,
'0000000043': four,
'bpr': self.get_body_argument('bpr'),
'pgnr': self.get_body_argument('pgnr'),
'wjbm': self.get_body_argument('wjbm'),
'wjbz': 'null',
'xumanyzg': 'zg',
'zgpj': self.get_body_argument("zgpj")
}
data = parse.urlencode(data, encoding='gbk').encode()
three = requests.post('http://211.82.47.2/jxpgXsAction.do?oper=wjpg', data=data, headers = head1)
three.close()
if b'back' in three.content:
self.render("Failed.html")
else:
self.render("Success.html")


class ResultShow(BaseHandler):
@gen.coroutine
def get(self):
uid = self.current_user
if not uid:
self.redirect('/login')
head1 = dict()
head1['Content-Type'] = 'application/x-www-form-urlencoded'
head1['Referer'] = 'http://211.82.47.2/jxpgXsAction.do?oper=listWj'
head1['Accept-Language'] = 'zh-CN'
head1['Cache-Control'] = 'no-cache'
head1['Accept'] = 'text/html,application/xhtml+xml,application/xml'
head1['Accept-Encoding'] = 'gzip, deflate'
head1['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'
head1['Cookie'] = uid
data = {
'bpr': self.get_argument('bpr'),
'bprm': self.get_argument("bprm"),
'currentPage': '1',
'oper': 'wjResultShow',
'page': '1',
'pageNo': '',
'pageSize': '20',
'pgnr': self.get_argument("pgnr"),
'pgnrm': self.get_argument('pgnrm'),
'wjbm': self.get_argument('wjbm'),
'wjbz': '',
'wjmc': self.get_argument('wjmc')
}
data = parse.urlencode(data, encoding='gbk').encode()
result = requests.post('http://211.82.47.2/jxpgXsAction.do', data = data, headers = head1)
result.close()
a = re.sub('href=\".*?\"','href=\"\"', result.text)
a = re.sub('src=\".*?\"', 'src=\"\"', a)
self.write(a)

class ShowAllScore(BaseHandler):
@gen.coroutine
def get(self):
uid = self.current_user
if not uid:
self.redirect('/login')
head = {
'Accept': 'image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*',
'Accept-Language': 'zh-CN',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
'Host': '211.82.47.2',
'Cookie': uid
}
all_score = requests.get('http://211.82.47.2/gradeLnAllAction.do?type=ln&oper=fainfo', headers = head)
all_score.close()
scoreSoup = BeautifulSoup(all_score.text, 'html.parser')
displayTag = [] #标题
for tag in scoreSoup.find_all('th' , class_='sortable'):
displayTag.append(str.strip(tag.text))
scoreData = [] #成绩数据
for score in scoreSoup.find_all('tr', class_='odd'):
subject = []
for data in score.find_all('td'):
subject.append(str.strip(data.text))
scoreData.append(subject)
counts = [] #学分统计
for font in scoreSoup.find_all('font'):
counts.append(str.strip(font.text))
self.render('ShowAllScore.html', displayTag = displayTag, scoreData = scoreData, counts = counts)

class SaveAllScore(BaseHandler):
@gen.coroutine
def get(self):
uid = self.current_user
if not uid:
self.redirect('/login')
#获取成绩单的cookie
#cjd = requests.post('http://211.82.47.2/reportFiles/student/cj_zwcjd_all.jsp', allow_redirects=False)
#cjd.close()
#cookie1 = cjd.headers['Set-Cookie']
#cookie = cookie1 + ';' + uid
header = {
'Accept':'*/*',
'Accept-Language': 'zh-CN',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
'Host': '211.82.47.2',
'Cookie': uid
}
cj = requests.get('http://211.82.47.2/reportFiles/student/cj_zwcjd_all.jsp', headers=header)
cj.close()
self.write(cj.text)


class Showbxqcjcx(BaseHandler):
@gen.coroutine
def get(self):
uid = self.current_user
if not uid:
self.redirect('/login')
head = {
'Accept': 'image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*',
'Referer':'http://211.82.47.2/menu/menu.jsp',
'Accept-Language': 'zh-CN',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
'Host': '211.82.47.2',
'Cookie': uid
}
cur_score = requests.get('http://211.82.47.2/bxqcjcxAction.do',headers = head)
cur_score.close()
scoreSoup = BeautifulSoup(cur_score.text, 'html.parser')
displayTag = [] #标题
for tag in scoreSoup.find_all('th' , class_='sortable'):
displayTag.append(str.strip(tag.text))
scoreData = [] #成绩数据
count = 0
for score in scoreSoup.find_all('tr', class_='odd'):
subject = []
for data in score.find_all('td'):
subject.append(str.strip(data.text))
count = count + 1
scoreData.append(subject)
self.render('Showbxqcjcx.html', displayTag = displayTag, scoreData = scoreData)

class ShowSubjectScore(BaseHandler):
@gen.coroutine
def get(self):
uid = self.current_user
if not uid:
self.redirect('/login')
num = self.get_argument('num')
head = {
'Accept': 'image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*',
'Referer':'http://211.82.47.2/menu/menu.jsp',
'Accept-Language': 'zh-CN',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
'Host': '211.82.47.2',
'Cookie': uid
}
cur_score = requests.get('http://211.82.47.2/bxqcjcxAction.do',headers = head)
cur_score.close()
scoreSoup = BeautifulSoup(cur_score.text, 'html.parser')
displayTag = [] #标题
for tag in scoreSoup.find_all('th' , class_='sortable'):
displayTag.append(str.strip(tag.text))
scoreData = [] #成绩数据
count = 0
for score in scoreSoup.find_all('tr', class_='odd'):
subject = []
for data in score.find_all('td'):
subject.append(str.strip(data.text))
count = count + 1
scoreData.append(subject)
self.render('ShowSubjectScore.html', subject = scoreData[int(num)])

class ShowTermScore(BaseHandler):
@gen.coroutine
def get(self):
uid = self.current_user
if not uid:
self.redirect('/login')
term = self.get_argument('term')
head = {
'Accept': 'image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*',
'Accept-Language': 'zh-CN',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
'Host': '211.82.47.2',
'Cookie': uid
}
all_score = requests.get('http://211.82.47.2/gradeLnAllAction.do?type=ln&oper=qbinfo&lnxndm=2016-2017学年秋(两学期)#2016-2017学年秋(两学期)', headers = head)
all_score.close()
scoreSoup = BeautifulSoup(all_score.text, 'html.parser')
terms = [] #存放学期
for i in scoreSoup.find_all('a'):
terms.append(i['name'])
tables = scoreSoup.find_all('table', id='user')
displayTags = [] #所有标题数据
scoreDatas = []
for table in tables:
displayTag = [] #标题
for tag in table.find_all('th' , class_='sortable'):
displayTag.append(str.strip(tag.text))
displayTags.append(displayTag)
scoreData = [] #成绩数据
for score in table.find_all('tr', class_='odd'):
subject = []
for data in score.find_all('td'):
subject.append(str.strip(data.text))
scoreData.append(subject)
scoreDatas.append(scoreData)
counts = [] #总计
for count in scoreSoup.find_all('td', height = "21"):
s = str.strip(count.text)
string = []
string.append(s[0:13])
string.append(s[13:29])
string.append(s[29:44])
string.append(s[44:])
counts.append(string)
self.render("ShowTermScore.html", displayTag = displayTags[int(term)], scoreData = scoreDatas[int(term)], term = terms[int(term)], count = counts[int(term)])
坚持原创技术分享,您的支持将鼓励我继续创作!