最近一周一直在帮家里小弟看高考志愿,因此更新的没那么频繁了,请你们见谅。html
在看各高校的往年分数时,忍不住手痒,想着能不能给它爬下来?哈哈,说干就干!python
以前无心中在这个网站发现有各个高校的历年录取分数线:https://gkcx.eol.cn。json
咱们的目标是用 Python 将下面页面的数据导出到 Excel:api
这个页面的 URL 是:https://gkcx.eol.cn/schoolhtm...,显然是须要一个 school_id
拼接而成的,那么如何获取这个 school_id 呢?微信
除非想办法爬取到全部院校的 school_id,这里我想着是从上面图中的搜索框进入:学习
这样,总体的业务流程咱们就理清楚了:网站
按下 F12
,能够看出搜索调用的 URL 是:https://gkcx.eol.cn/soudaxue/queryschool.html?&keyWord1=南京邮电大学
,可是咱们发现该请求的 response 里并无高校列表,因此猜想这里是有二次数据请求获取到高校的列表,而后解析显示到页面的。spa
顺着请求流,咱们看到了这么一个请求:excel
而且它的 response 恰好是一个包含高校信息的 json,到这里应该仍是顺利的,咱们只要从这个 json 里解析出咱们想要的东西,而后继续后面的步骤就能够了。要注意该请求的 Referer
。code
可是在解析这个 json 时会遇到一个小问题,返回的数据格式是这样的:
({ "totalRecord": {"num": "2"}, "school": [ { "schoolid": "160", "schoolname": "南京邮电大学", ... });
它是被 ();
包围着的,不是一个合法的 json 数据,这里须要对其进行处理后才能解析 json:
# 返回数据包含 ();,须要特殊处理 text = ((response.text).split(');',1)[0]).split('(',1)[1] j = json.loads(text)
学校的详情页面是:https://gkcx.eol.cn/schoolhtm...,一样的套路,在点击后 response 里并无分数线数据,我想也是二次请求吧,果真在请求流里找到了这个:
这里的两个请求恰好将高校的每一年分数线和各专业的分数线以 XML 的格式返回,Very Good!
下面要作的就是 XML 解析啦。
这里咱们使用 xml.etree.ElementTree
来解析 XML:
<areapionts> <areapiont> <year>2017</year> <specialname>软件工程(嵌入式培养)</specialname> <maxfs>369</maxfs> <varfs>366</varfs> <minfs>364</minfs> <pc>一批</pc> <stype>理科</stype> </areapiont>
因为数据比较规整,解析也很简单:
areapionts = ET.fromstring(response.text) for areapiont in areapionts: print(areapiont.find('year').text) print(areapiont.find('specialname').text)
Excel 的写入须要借助于 openpyxl
模块。
>>> import openpyxl >>> wb = openpyxl.Workbook() # 初始时会生成一个 sheet 页 >>> wb.sheetnames ['Sheet'] # 建立 sheet 页 >>> wb.create_sheet(index=0,title='First') <Worksheet "First"> # 获取全部 sheet 页 >>> wb.sheetnames ['First', 'Sheet'] # 删除 sheet 页 >>> wb.remove(wb['Sheet']) >>> wb.sheetnames ['First'] >>> sheet = wb['First'] # 设置单元格 >>> sheet['A1'] = '省份' >>> sheet['B1'] = '学校' # 设置指定的单元格 >>> sheet.cell(1,3).value='test' >>> wb.save('test.xlsx')
def gen_excel(school,xml,wb): sheet = wb.create_sheet(title='各专业历年录取分数线') sheet.column_dimensions['B'].width = 40 sheet['A1'] = '年份' sheet['B1'] = '专业' sheet['C1'] = '最高分' sheet['D1'] = '平均分' sheet['E1'] = '最低分' sheet['F1'] = '批次' sheet['G1'] = '录取批次' areapionts = ET.fromstring(xml) column = 1 for areapiont in areapionts: column += 1 sheet.cell(column,1).value = areapiont.find('year').text sheet.cell(column,2).value = areapiont.find('specialname').text sheet.cell(column,3).value = areapiont.find('maxfs').text sheet.cell(column,4).value = areapiont.find('varfs').text sheet.cell(column,5).value = areapiont.find('minfs').text sheet.cell(column,6).value = areapiont.find('pc').text sheet.cell(column,7).value = areapiont.find('stype').text wb.save('{}.xlsx'.format(school['schoolname']))
$ python gkcx.py Please the school name:南京邮电大学 共检索到 2 个高校:['南京邮电大学', '南京邮电大学通达学院'] 数据获取完成,已下载到脚本目录
结果看着还能够,可是仍是有问题的,由于各省的分数线确定是不同的,这里默认检索出的是学校所在省的分数线,所以若要获取在其余省的分数线,还须要进一步处理,有兴趣的同窗不妨动手试一下。后台回复「高考」能够获取源码。
若是以为有用,欢迎关注个人微信,一块儿学习,共同进步,不按期推出赠书活动~