文章目录
- 1 总体介绍
- 2 获取token的思路
- 3 通过token访问成绩页面
- 4 解析成绩页面返回的json
- 5 导出数据到Excel
1 总体介绍
近日学校上线了家长督学系统。通过该系统,输入学生的证件号,即可查询学生的成绩。密码为证件号的后六位,刚好我有同学们的证件号。准备通过Python读取Excel中保存的证件号,然后模拟登陆,获得成绩信息,然后将所有同学的成绩输出到Excel,以便进行下一步的分析。
2 获取token的思路
通过抓包工具,可以看出在点击登录后,出现了“login”开头的一个请求,并在response中发现了“登陆成功”的字样。
在这个json数据的后面,还找到了一个“token”,我猜测这个token就是用户的标识,标志着登陆成功,可能在后面涉及到用户信息查询的时候会用到这个token。
然后查看请求的信息,使用post方式请求,url就是一个固定的前缀拼接上用户的账号和密码,而我刚好有这些信息。
然后进入查询成绩的页面进行查询,发现果然,token出现在了请求的头文件里,于是爬虫的思路就有了。第一步就是通过登录,获得到用户的token。
那就开始写代码啦,首先通过excel函数,将所需的账户名和密码从excel文件中提取出来。
密码为ID的后几位,截取字符串获得密码的操作在main函数中完成了,此处不予展示。
def excel(i):
global user
global pwd
workBook = xlrd.open_workbook('data/all.xls')
sheet1_content1 = workBook.sheet_by_index(0);
id=sheet1_content1.cell(i, 0).value
print(id)
return id
然后通过拼接字符串的形式,将上一步中获取的账号和密码在Request URL中拼接出来,伪造一个浏览器的请求头,开始进行爬虫。然后将爬虫获取到的对象转换为json格式,发现该数据类型为字典,通过字典的基本语法,提取出了token的值。
def sprider1():
head1 = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3861.400 QQBrowser/10.7.4313.400'
}
url='http://jwxtapp.nmu.edu.cn:8080/bfmzdxhd/patriarch/login?userNo='+user+'&pwd='+pwd
r1=requests.get(url,headers=head1)
r1.encoding='utf-8'
json_token=r1.json()
token=json_token['data']['token']
# print(token)
return token
3 通过token访问成绩页面
经过观察发现,成绩信息是向这个链接发送请求,然后返回的json数据中得到的。同时需要注意在请求头中添加上一步获得的token。
代码实现如下,通过爬虫获得了返回的对象,成绩中有一些无用的字段,在此不做解析,只把它直接返回即可。
def sprider2(token):
head2 = {
'Referer': 'http://jwxtapp.nmu.edu.cn:8080/jzdxsjd/',
'token': token,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3861.400 QQBrowser/10.7.4313.400'
}
r2 = requests.get('http://jwxtapp.nmu.edu.cn:8080/bfmzdxhd/student/termGPA?semester=&type=', headers=head2)
r2.encoding='utf-8'
temp=r2.json()
grade=temp["data"][0]
return grade
4 解析成绩页面返回的json
该函数主要用于解析字段,需要用到的字段有:课程名,学分,成绩。所以建立几个空列表,用于存储。然后遍历整个grade列表,提取有用的子弹,并append入total列表,最后将列表total与字符串studentName在字典dic中对应起来,实现了一个学生全部成绩的存储。
def extract(grade):
global dic
i=0
courseName=[]
credit = []
score = []
total=[]
studentName=grade["name"]
x=len(grade['achievement'])
while i<x:
courseName.append(grade['achievement'][i]['courseName'])
credit.append(grade['achievement'][i]['credit'])
score.append(grade['achievement'][i]['fraction'])
total.append(grade['achievement'][i]['courseName'])
total.append(grade['achievement'][i]['credit'])
total.append(grade['achievement'][i]['fraction'])
i=i+1
dic[studentName]=total
5 导出数据到Excel
使用函数分别遍历字典dic的key和value,并调用函数将遍历出来的信息写入excel中,因为value的值仍然是一个列表,所以需要用到循环再次进行遍历。
最后就实现了Excel中一个学生的姓名,后面一行对应着其所有的成绩的展示效果。
key=[]
values=[]
table={"1":"里面是不能公开的成绩的json数据"}
for i in dic.keys():
key.append(i)
for j in dic.values():
values.append(j)
print(key)
print(values)
list1=key
output = open('names.xls','w',encoding='gbk')
output.write('name\tgender\tstatus\tage\n')
for i in range(len(list1)):
output.write(str(list1[i])) #write函数不能写int类型的参数,所以使用str()转化
output.write('\t') #相当于Tab一下,换一个单元格
output.write('\n') #写完一行立马换行
output.close()