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

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

项目简介:

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

项目工程文件目录:

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

图:项目工程文件

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

图:网页文件

程序功能和效果图如下:


登录界面:

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

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

图:登录界面

菜单界面:

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

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

图:菜单界面
-----

查看本学期成绩:

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

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

图:查看本学期成绩
--------------

查看课程详细成绩:

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

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

图:查看课程详细成绩
-----

查看各学期成绩:

查看各学习的成绩,可以统计各学习的总学分,通过课程数等。
Python实现爬取教务处成绩系统

图:查看各学期成绩
----

评教界面:

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

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

图:评教界面
---

Python实现代码

demo.py

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

该程序为程序实现的主体。

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)])