[Python]基于python制作上海海洋大学绩点计算器


| 发布于:2016-04-04

初衷

最早只是觉得手工计算绩点比较麻烦,so用js写了一个绩点计算器,当然咯,之前是有人写过的不过现在我打算让其完成自动化的过程,首先了,不得不提提海大的学风系统了 它大量使用了iframe框架,虽然说作为一个站内站点,不需要做SEO但是讲道理,这里面js跨域的问题就觉得麻烦么? so,我把最初的js的版本放弃了。

当然,我不得不提一句,由于新学期开始了,so这个办法目前是不能获得分数的(因为页面就还没放上内容)

程序设计

这里就不去把抓包数据分析了,直接上代码

首先讲述一下思路,因为我们学校使用了类似于sessionid的客户端cookie(不理解为什么这么做),so我们不能直接访问入口,必须要访问门户获取一次cookie

1
2
3
4
5
6
7
8
9
10
11
12
#登录的主页面  
hosturl = 'http://urp.shou.edu.cn/'
#post数据接收和处理的页面(我们要向这个页面发送我们构造的Post数据)  
posturl = 'http://urp.shou.edu.cn/loginAction.do'
#设置一个cookie处理器,它负责从服务器下载cookie到本地,并且在发送请求时带上本地的cookie  
cj = cookielib.LWPCookieJar()
cookie_support = urllib2.HTTPCookieProcessor(cj)
opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)
urllib2.install_opener(opener)

#打开登录主页面(他的目的是从页面下载cookie,这样我们在再送post数据时就有cookie了,否则发送不成功)  
h = urllib2.urlopen(hosturl)

接下来我们读取一下设置好的用户名和密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cf = ConfigParser.ConfigParser()
cf.read("./config.conf")
#读取用户全局设置
username = cf.get("globe","username")
password = cf.get("globe", "password")

#构造header,一般header至少要包含一下两项。学校抓包数据表明为这两项
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1',
                 'Referer' : 'http://urp.shou.edu.cn/'}
#构造Post数据  
postData = {
                      'zjh' : username,
                      'mm' : password,
                      }

print '检验post数据是否正确'
print postData

#需要给Post数据编码  
postData = urllib.urlencode(postData)

然后通过urllib2提供的request方法来向指定Url发送我们构造的数据,并完成登录过程

1
2
3
4
5
6
7
request = urllib2.Request(posturl, postData, headers)
print '校验request是否成功'
print request
response = urllib2.urlopen(request)
text = response.read()
print '校验是否进入学校登陆页面'
print text

接下来获取我们学分页面

1
2
3
4
5
6
7
8
9
10
##构造get的header,一般header至少要包含一下两项。学校抓包数据表明为这两项
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1',
                 'Referer' : 'http://urp.shou.edu.cn/menu/s_main.jsp'}
##我们需要get的页面 
geturl = 'http://urp.shou.edu.cn/bxqcjcxAction.do'
request = urllib2.Request(geturl)
#获得返回值
response = urllib2.urlopen(request)
text = response.read()
print '校验是否获得目标学分'

获得了之后我们把它保存在同级目录下,然后在结尾处加上我们的js代码,这里我已经把js处理成单行的,恐怕没有什么好的办法还原了,so将就着看吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#字符串格式转码
text = text.decode('GBK').encode('UTF-8')
#替换计算系统
regex = re.compile("</html>")
upload='<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script><script>function getPoints(t){return t.match("通过")?3.3:t.match("优秀")?3.3:t.match("良好")?2.3:t.match("通过")?1:t>=90?4:t>=85?3.7:t>=82?3.3:t>=78?3:t>=75?2.7:t>=72?2.3:t>=68?2:t>=66?1.7:t>=64?1.5:t>=60?1:0}function getPoint(t,n,r){return sumt=0,suml=0,$.each(t,function(t){0!=t&&(sumt+=r[t]*n[t],suml+=n[t])}),sumt/suml}$(document).ready(function(){var t=new Array,n=new Array,r=new Array;$("#user tr").each(function(e){0!=e&&(r[e]=parseFloat($.trim(this.children[4].innerHTML)),n[e]=$.trim(this.children[6].innerHTML),t[e]=getPoints(n[e]))});var e=getPoint(n,r,t);alert(e)});</script></html>'
text = re.sub(regex,upload,text)
#将文件标示为utf类型
regex = re.compile("<head>")
upload='<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
text = re.sub(regex,upload,text)
print text
#打开文本
# text = unicode(text, "utf-8")
f = open(".\index.html","wt")
#输出到文本
f.write(text)
#关闭文本
f.close()
#打开文件
url = '.\index.html'
webbrowser.open(url)

完整代码如下

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
#!/usr/bin/python  
#coding:utf-8
import HTMLParser
import urlparse
import urllib
import urllib2
import cookielib
import string
import re
import sys
import webbrowser
import codecs
import ConfigParser

cf = ConfigParser.ConfigParser()
cf.read("./config.conf")
#读取用户全局设置
username = cf.get("globe","username")
password = cf.get("globe", "password")
#登录的主页面  
hosturl = 'http://urp.shou.edu.cn/'
#post数据接收和处理的页面(我们要向这个页面发送我们构造的Post数据)  
posturl = 'http://urp.shou.edu.cn/loginAction.do'
#设置一个cookie处理器,它负责从服务器下载cookie到本地,并且在发送请求时带上本地的cookie  
cj = cookielib.LWPCookieJar()
cookie_support = urllib2.HTTPCookieProcessor(cj)
opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)
urllib2.install_opener(opener)

#打开登录主页面(他的目的是从页面下载cookie,这样我们在再送post数据时就有cookie了,否则发送不成功)  
h = urllib2.urlopen(hosturl)

#构造header,一般header至少要包含一下两项。学校抓包数据表明为这两项
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1',
                 'Referer' : 'http://urp.shou.edu.cn/'}
#构造Post数据  
postData = {
                      'zjh' : username,
                      'mm' : password,
                      }

print '检验post数据是否正确'
print postData

#需要给Post数据编码  
postData = urllib.urlencode(postData)

#通过urllib2提供的request方法来向指定Url发送我们构造的数据,并完成登录过程  
request = urllib2.Request(posturl, postData, headers)
print '校验request是否成功'
print request
response = urllib2.urlopen(request)
text = response.read()
print '校验是否进入学校登陆页面'
print text

##构造get的header,一般header至少要包含一下两项。学校抓包数据表明为这两项
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1',
                 'Referer' : 'http://urp.shou.edu.cn/menu/s_main.jsp'}
##我们需要get的页面 
geturl = 'http://urp.shou.edu.cn/bxqcjcxAction.do'
request = urllib2.Request(geturl)
#获得返回值
response = urllib2.urlopen(request)
text = response.read()
print '校验是否获得目标学分'
#字符串格式转码
text = text.decode('GBK').encode('UTF-8')
#替换计算系统
regex = re.compile("</html>")
upload='<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script><script>function getPoints(t){return t.match("通过")?3.3:t.match("优秀")?3.3:t.match("良好")?2.3:t.match("通过")?1:t>=90?4:t>=85?3.7:t>=82?3.3:t>=78?3:t>=75?2.7:t>=72?2.3:t>=68?2:t>=66?1.7:t>=64?1.5:t>=60?1:0}function getPoint(t,n,r){return sumt=0,suml=0,$.each(t,function(t){0!=t&&(sumt+=r[t]*n[t],suml+=n[t])}),sumt/suml}$(document).ready(function(){var t=new Array,n=new Array,r=new Array;$("#user tr").each(function(e){0!=e&&(r[e]=parseFloat($.trim(this.children[4].innerHTML)),n[e]=$.trim(this.children[6].innerHTML),t[e]=getPoints(n[e]))});var e=getPoint(n,r,t);alert(e)});</script></html>'
text = re.sub(regex,upload,text)
#将文件标示为utf类型
regex = re.compile("<head>")
upload='<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
text = re.sub(regex,upload,text)
print text
#打开文本
# text = unicode(text, "utf-8")
f = open(".\index.html","wt")
#输出到文本
f.write(text)
#关闭文本
f.close()
#打开文件
url = '.\index.html'
webbrowser.open(url)