前言
又到了一年两度的四六级成绩查询的时候啦,不知道小伙伴们过了没有呢?
今天我们来介绍如何使用python
来批量查询四六级成绩。听起来好像很高大上,但实现起来非常容易哦…
之前的爬虫博文中我也说过,爬虫最重要的一步不是如何编写程序,而是分析网页的结构。
四六级成绩查询可以使用如下网址:
http://cet.neea.edu.cn/html1/folder/22023/595-1.htm
分析网页
浏览器打开,随便进入一个入口,该网页中,按F12
,我们来分析一下这个查询页面:

输入相关信息后,点击查询,可以看到对应的成绩,我们在控制台中,找找有什么好的接口可以直接查询到成绩,不一会儿,我们找到了下面这个文件:

这个文件的请求地址是:
http://cachecloud.neea.cn/api/latest/results/cet?e=CET_202112_DANGCI&km=2&xm=罗颖&no=4311******&v=
这个url
地址有几个参数,我们关心的是xm
(姓名)和no
(身份证号),我们来看看这个请求的响应长什么样子:

显然,该请求返回的是一json
串,我们来观察这个json
串:
{
"xx":"******大学", (考生所在大学)
"tlmk":0,
"km":2,
"ky_sco":"",
"zkzh":"43003******", (准考证号)
"sfz":"43110******", (身份证号)
"score":"401", (六级成绩)
"sco_lc":"94", (听力部分成绩)
"ky_zkz":"–",
"xm":"***", (姓名)
"sco_rd":"175", (阅读部分成绩)
"sco_wt":"132", (写作部分成绩)
"id":"212243003004401",
"cjd":0,
"code":200 (状态码)
}
这里… "zkzh
" 表示 "准考证号","sfz
" 表示 "身份证",多少有点大病哈哈。。。
此外,如果查询不到(即没有参加六级考试或输入的信息有误),响应会是什么样的呢?

很显然,我们可以使用 "code
" 这个键来判断某个学生是否参加了当次的六级考试(当然,前提是你的学生信息表中的信息没有错误…)。
爬取成绩
有了以上分析,我们就可以开始我们批量爬取六级成绩了。
首先,我们需要批量的考生信息数据,载体有很多,比如最常见的,excel
表:

在数据导入的过程中需要一点 pandas
的知识,不会的小伙伴们可以去学一学哦。
在使用 pandas
处理得到的 DataFrame
中,我们添加几个字段用于存储爬取到的信息:

值得注意的是,如果直接调用之前分析的那个接口,会显示错误码403
,这说明对方的服务器把我们已经将我们视为爬虫。一般的方法是,在请求的过程中,我们添加请求头,模拟我们使用浏览器进行查询。
请求头怎么弄呢?控制台上有现成的:

请求头中的所有属性中,最重要的是 Cookie属性
(有兴趣的小伙伴们可以去查一查),简单来说,Cookie就是由服务器发给客户端(此处为浏览器)的特殊信息,这些信息存放在客户端(浏览器),然后客户端(浏览器)每次向服务器发送请求的时候都会带上这些特殊的信息,向浏览器表明自己的身份。
通俗来说,正因有了Cookie
,对方的服务器才不会认为当前的请求是一个爬虫发出的,也就不会响应错误码403
了,这样我们便可以拿到我们想要的数据。其余的属性,大家可选择性复制粘贴:
1 2 3 4 5 6 7 8 9 10 11 12
| headers = { 'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Host': 'cachecloud.neea.cn', 'Origin': 'http://cet.neea.cn', 'Referer': 'http://cet.neea.cn/', 'Cookie': 'Hm_lvt_dc1d69ab90346d8ee02f18510292577=1629958972,1629961007,1629989056,1629992054; community=Home; language=1; http_waf_cookie=f27d75db-23f7-4aa938445a95fb8092bcad0ba73630744bd3', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/98.0.4758.102 Safari/537.36 ' }
|
接着,就是一些简单的爬取代码了。我们使用 requests
库来完成爬取工作。完整代码如下:
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
| from time import sleep import requests import pandas as pd
""" :author: 易果啥笔 :date: 2022-01-24 :apiNote: 批量查询四六级成绩
"""
data = pd.read_excel('data.xls')
data.insert(7, '准考证号', '') data.insert(8, '六级成绩', '') data.insert(9, '听力部分', '') data.insert(10, '阅读部分', '') data.insert(11, '写作部分', '')
headers = { 'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Host': 'cachecloud.neea.cn', 'Origin': 'http://cet.neea.cn', 'Referer': 'http://cet.neea.cn/', 'Cookie': 'Hm_lvt_dc1d69ab90346d48ee2f18510292577=1629958972,1629961007,1629989056,1629992054; community=Home; language=1; http_waf_cookie=f27d75db-23f7-4aa938445a95fb8092bcad0ba73630744bd3', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/98.0.4758.102 Safari/537.36 ' }
params_list = [] for i in range(len(data)): params_list.append({ 'e': 'CET_202112_DANGCI', 'km': 2, 'xm': data.iloc[i, 2], 'no': data.iloc[i, 6] })
url = "http://cachecloud.neea.cn/api/latest/results/cet"
for i in range(len(data)): response = requests.get(url, params_list[i], headers=headers) print("*******************************************************************") print("开始爬取%s的六级成绩......" % params_list[i]['xm']) json_data = response.json()
if json_data['code'] == 200: data.iloc[i, 7] = json_data['zkzh'] data.iloc[i, 8] = json_data['score'] data.iloc[i, 9] = json_data['sco_lc'] data.iloc[i, 10] = json_data['sco_rd'] data.iloc[i, 11] = json_data['sco_wt'] info = '%d:%s查询成功,成绩为:%s' % ((i + 1), params_list[i]['xm'], json_data['score']) print(info) else: print('%d:%s未参加六级考试...' % ((i + 1), params_list[i]['xm'])) print("*******************************************************************")
sleep(0.3)
print("已全部查询完毕,正在导出到csv......")
data.to_csv('grade.csv') print("导出完毕.")
|
运行截图:
程序跑完后,在当前目录下会生成指定的 grade.csv
文件,里面有所有学生的六级详细成绩。涉及隐私问题,这里就不截图了哈。
是不是挺简单的呢?