利用python进行哈工程教务系统中的绩点计算

来源:互联网 发布:excel07建立数据透视表 编辑:程序博客网 时间:2024/06/10 08:55

作为学生党,计算每个学期的平均成绩是头等大事,但是多数教务系统并没有提供这项功能,东学西读网站虽然有一个在线的GPA计算器,但是最近也不能登录哈工程的教务获取成绩了,所以我就借助刚刚学习了一点的简单的爬虫,来完成这项任务。

首先,分析哈工程教务处成绩查询页面,与大多数教务系统页面相同,都是通过POST提交账号、密码等信息,不过哈工程有验证码,我们现在暂时不集成自动识别验证码的功能,于是整体思路就是认证cookie,然后获取验证码图片并显示,手工输入学号、密码、验证码,最后下载页面并分析html。

验证码的显示我利用了PIL库,需要额外进行下载安装,其余的库应该都是python自带的,使用了最原始的正则进行匹配,尤其是在匹配成绩时,由于成绩是一个表格,所以匹配略显复杂,主要思路就是先匹配出成绩表格的全部,然后逐行匹配,拿到所有成绩信息,最重要的信息无非就是学分和成绩了,这两个信息都出现在固定的位置,因此不难获得,另外学校存在考查课,考查课的成绩对应关系也已经集成在了一个字典当中,方便调用。

哈工程的教务成绩是按照学期计算的,在URL上没有显示,而是利用POST的方式做请求返回数据,因此当我们需要选择不同的学期时,还需要POST一个对应的学期代码,这个代码我已经集成在了一个字典的数据结构中。

代码如下:

#encoding=utf-8import urllib2,cookielib,urllibimport cStringIO,stringimport reimport Imageclass Tool:    #去除img标签,7位长空格    removeImg = re.compile('<img.*?>| {7}| ')    #删除超链接标签    removeAddr = re.compile('<a.*?>|</a>')    #把换行的标签换为\n    replaceLine = re.compile('<tr>|<div>|</div>|</p>')    #将表格制表<td>替换为\t    replaceTD= re.compile('<td>')    #把段落开头换为\n加空两格    replacePara = re.compile('<p.*?>')    #将换行符或双换行符替换为\n    replaceBR = re.compile('<br><br>|<br>')    #将其余标签剔除    removeExtraTag = re.compile('<.*?>')    def replace(self,x):        x = re.sub(self.removeImg,"",x)        x = re.sub(self.removeAddr,"",x)        x = re.sub(self.replaceLine,"\n",x)        x = re.sub(self.replaceTD,"\t",x)        x = re.sub(self.replacePara,"\n    ",x)        x = re.sub(self.replaceBR,"\n",x)        x = re.sub(self.removeExtraTag,"",x)        #strip()将前后多余内容删除        return x.strip()class HEU_Score(object):    def __init__(self,baseURL):        self.baseURL = baseURL        self.cookie = cookielib.CookieJar()        self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookie))        self.opener.addheaders.append(('User-Agent','Mozilla/5.0 (Windows NT 5.1; rv:25.0) Gecko/20100101 Firefox/25.0'))        self.tool = Tool()  # 字符串处理工具        self.scoreDict = {u'优秀':95,u'良好':85,u'中等':75,u'及格':65} # 考查课成绩换算字典        # 学期对应POST代码        self.semster = {'09-10-1':1,'09-10-2':2,'10-11-1':3,'10-11-2':4,'11-12-1':5,'11-12-2':6,'12-13-1':7,'12-13-2':8,                        '13-14-1':9,'13-14-2':10,'14-15-1':11,'14-15-2':12,'15-16-1':13,'15-16-2':21}    def register(self,URL):        self.opener.open(URL)        imgsrc = "http://jw.hrbeu.edu.cn/ACTIONVALIDATERANDOMPICTURE.APPPROCESS" # 验证码URL        userid =  raw_input("学号:")        pwd = raw_input("密码:")        # 显示验证码图片并人工输入        res = self.opener.open(urllib2.Request(imgsrc))        tempIm = cStringIO.StringIO(res.read())        im = Image.open(tempIm)        im.show()        agnomen = raw_input("验证码:")        #构建要POST的数据        postdata = urllib.urlencode({            'WebUserNO': userid,            'Password': pwd,            'Agnomen': agnomen,            'submit.x': '20',            'submit.y': '11',            'applicant':'ACTIONQUERYSTUDENTSCORE',        })        req = urllib2.Request(url = self.baseURL,data = postdata)        try:            response = self.opener.open(req)            return response.url        except urllib2.URLError,e:            if hasattr(e,'reason'):                print e.reason    def getScore(self,semsterCode):        scoreurl = self.register(self.baseURL)        postdata = urllib.urlencode({'YearTermNO':self.semster[semsterCode]})        req = urllib2.Request(scoreurl,postdata)        try:            response =  self.opener.open(req)            #在整个页面中匹配成绩表格            html =  response.read().decode("gbk")            pattern = re.compile('<table width="100%" border="1" bordercolor="#666666" style="BORDER-COLLAPSE:collapse" cellspacing="0" class=tableborder>(.*?)<\/table>',re.S)            course = re.findall(pattern,html)            table = course[0]            # 在成绩表格内匹配所有的项目,同时计算平均成绩            p2 = re.compile('<tr class="color-row">(.*?)</tr>',re.S)            row = re.findall(p2,table)            scoreInfo = []            sumScore = 0.0            creditNum = 0.0            print len(row)            for item in row:                singleInfo = []                p3 = re.compile('<td nowrap>(.*?)</td>',re.S)                singleInfo.append(self.tool.replace(re.findall(p3,item)[0]))                print self.tool.replace(re.findall(p3,item)[0])                p4 =  re.compile('<td align="center" nowrap>(.*?)</td>',re.S)                infos = re.findall(p4,item)                # print infos[3]                # print infos[5]                for info in infos:                    print info                    singleInfo.append(info) #记录条目信息                # 计算平均成绩                if infos[1] == u'考查':                    sumScore += float(infos[3])*self.scoreDict[infos[5]]                else:                    sumScore += float(infos[5])*float(infos[3])                creditNum += float(infos[3])                scoreInfo.append(singleInfo)            print sumScore/creditNum            print scoreInfo            return scoreInfo,sumScore/creditNum        except urllib2.URLError,e:            if hasattr(e,'reason'):                print e.reasonurl = "http://jw.hrbeu.edu.cn/ACTIONLOGON.APPPROCESS"myscore = HEU_Score(url)#myscore.register()myscore.getScore('14-15-2')


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 网上买东西手机号写错了怎么办 二类工资卡过万怎么办 淘宝发货地址写错怎么办 淘宝发货地址写错了怎么办 淘宝不能代付了怎么办 支付宝付款码被盗刷怎么办 地方选举追究不到相关责任人怎么办 天正建筑画个直线找不到怎么办 Wi-Fi模块不支持多播怎么办? 魅族手机屏幕点不动怎么办 uc打开网页很慢怎么办 京东手机号码无法登录怎么办 织梦系统网站没收录怎么办 电脑开机出现一堆乱码怎么办 电脑文件夹出现乱码打不开怎么办 电脑出现f1和f2怎么办 电脑中韩文内容显示乱码怎么办 入驻shopee没身份证怎么办 液相色谱柱柱压降低怎么办 c18色谱柱堵了怎么办 色谱柱进空气了怎么办 宫颈评分只有3分怎么办 淘宝鞋子售后退货商家拒收怎么办 退货申通cp原因怎么办 运费险赔的少怎么办 淘宝卖游戏账号恶意退款怎么办 淘宝账号体检虚拟违规怎么办 京东虚拟单被骗怎么办 网络公选课挂科怎么办 淘宝评论被商家关闭怎么办? 皇冠车钥匙丢了怎么办 皇冠行李箱钥匙丢了怎么办 淘宝主推产品扣两分怎么办 淘宝直通车宝贝排查下架怎么办 滴滴车龄超过8年怎么办 购物车超120了怎么办 没发货申请退款卖家不处理怎么办 淘宝卖家帐号被骗了怎么办 淘宝网下单忘了用返利网怎么办 该地域无法观看此直播怎么办 宝宝喝了有活虫的奶粉怎么办