python 3爬取 全国高校对四川历年招生数据(文理省控线,文理专业线)存入Excel表(重构)

原文章地址:https://blog.csdn.net/memory_qianxiao/article/details/82388370

由于很多朋友需要这种数据,因为发布以来,有很多人再问我要源代码,我也给了,直到3月10多号某一天,有人告诉我,运行后没有数据,我自己也去测试一下果然没有数据,然后简单排查发现,是请求的网址变了....由于在准备蓝桥杯比赛,在做题,没有仔细排查,后来仔细排查,发现网址请求变了是一回事,重点是网站采用了ajax技术,数据不在网页源代码里面,是通过ajax局部请求数据,然后加载到网页中的...所以需要去请求ajax地址,拿到数据解析。。。接下来解释重构过程,虽然解析麻烦了,但是代码量减少了,只需要200行的样子...就可以了。

提示由于网站每隔大概三个月的样子,就会维护更新,导致代码不能使用,而我还是应届毕业生,弄论文,做毕设,找工作,以后没有特情况,我是不会维护这个代码了,如果有需要的人,我这两篇博客中里面写了分析思路和过程,以及代码和注释,可以给你们参考学习~希望大家主动自己破解,提高思维和分析能力~而我本人时间和精力也有限,望体谅~    time:2020/5/20

开发环境:python 3.6 +pycahrm 

第三放库:request(网页级请求库),xlwt(excel操作库),json(python和json互转的库)

由于在原文章详细写过爬取过程,这次就不写这么详细了,想详细学习,了解,请参考原文章:https://blog.csdn.net/memory_qianxiao/article/details/82388370(虽然代码没法用了,但是思路重要呀,毕竟学习思想最重要,代码逻辑是你自己思想的体现)

提示:由于网站再次更新,不过这次更新就是换汤不换药,把请求的API换了,导致代码不能使用,只需要在原请求的ajax请求地址更改成如下就好:(感谢江苏地区的路祎唯同学指出)。最终代码完整在更新一次(4月30日   7月19更新能用的代码请点击下面GIthub:)。

同时该网站增加一点反爬措施, 我们需要把请求伪装成浏览器,所以还需要在请求的时候还要增加一个请求头,设置如下:

更新时间:2019年7月19      最新可用源码点击GitHub传送门:点我进入,GitHub传送门~

老规矩,镇楼图如下(爬取的一部分):一个excel4页,理科专业线,文科专业线,理科省控线,文科省控线

 一:下是分析过程:由于网站更新变化后,数据在ajax中,所以对网址请求没用了,下面给出逻辑分析:

先按F12进入开发者模式,点击network,按住XHR,在随便点个大学进去,发现每点年份或者文理科,都会出现一个api,数据都返回在api里面,所接下来分析的关键是如何分析拿到api里面的数据。

二:分析api里面的headers分析如下:

请求url是:https://gkcx.eol.cn/api

请求方法是:POST!POST!POST!很重要,不是get方法。

请求参数:post请求参数是

而我们拿数据最重要的就是这里的请求参数:

local_province_id:是省份的代号,网站更新后,都是自动定位的,会选择当前ip的定位位置,也就是定位后的代号自动填上,所以如果需要爬取其他地方的数据,可以更改请求参数,自己省份代号,需要自己去试。

local_type:是文理科代号,1是理科,2是文科,可以自己去测试,每点击一次就会有一个新的api去查看就行了。

school_id:是学校的id,所以需要查哪个学校就更改id就行

uri:"hxsjkqt/api/gk/score/province"是省控线  hxsjkqt/api/gk/score/special是专业线

year:是爬取的年份 也就是需要爬取哪一年就给year哪年参数

所以请求的是时候用request.post()方法,并且把上面的参数传进去。

这里附上全国34省的名称以及对应的代码:

北京:11
天津:12
河北:13
山西:14
内蒙古:15
辽宁:21
吉林:22
黑龙江:23
上海:31
江苏:32
浙江:33
安徽:34
福建:35
江西:36
山东:37
河南:41
湖北:42
湖南:43
广东:44
广西:45
海南:46
重庆:50
四川:51
贵州:52
云南:53
西藏:54
陕西:61
甘肃:62
青海:63
宁夏:64
新疆:65
台湾:71
香港:81
澳门:82


三:由于不知到学校的id还是采取暴力的方式,从30开始到 3000暴力循环学校id,然后拼接网址,请求。

还是定义三个函数,main()函数入口,get_html()请求信息,get_info()得到学校信息,并且保存到excel里面。代码里面都有注释,重复的就没有注释,是一样的。不过可能有以下报错,所以还是采用断点续爬,也就是每次都会打印网址,后面有个学校id,如果哪次报错继续更改否for循环起点,如果有大神知道这种报错解决方法,欢迎留言指导,感激不尽.

 全代码如下:excel保存路径换成自己的文件路径就ok了。

# -*- coding: utf-8 -*-
# @Filename: 全国高校录取数据重构.py
# @Time    : 2019/3/22 16:49
# @Author  : LYT
"""

"""
import requests,re,xlwt,json
from bs4 import BeautifulSoup
def Get_html(url,data):
    try:
        headers = {
            'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3676.400 QQBrowser/10.4.34"
        }#更新后添加的请求头,伪装成浏览器
        r=requests.post(url,params=data,headers=headers)#带请求参数params,同时把headers传进去
        r.encoding=r.apparent_encoding
        print("请求服务成功!")
        print(r.text)
        return r.text
    except:
        print("请求失败")
def Get_info(url,id):
    url_api = "https://gkcx.eol.cn/gkcx/api"#更新后请求ajax api  
    #请求参数信息
    data = {
        'local_province_id': '51',  # 省份 51为四川  默认是自动定位的地方
        'local_type_id': 1,  # 理科为1,文科为2,
        'school_id': '30',  # 学校id
        'uri': "hxsjkqt/api/gk/score/province",  # 专业线special     省线province
        'year': 2018  # 年份 网站更新后 省录取线2014 -2018  专业录取线2014-2017
    }
    info_like=[]#存理科省线信息列表
    info_wenke=[]#存文科省线信息列表
    special_like=[]#存理科专业信息列表
    special_wenke=[]#存文科专信息业表
    name=""
    for i in range(2014,2019):#请求2014-2018的省控线信息

        data['year']=i #更换参数年份
        data['school_id']=id#更换学校id
        data['local_type_id']=1#更换为理科
        infoes=json.loads(Get_html(url_api,data))
        # print(info)
        # print(info['data']['item'])
        #存理科省录取线
        if len(infoes['data']['item'])==0:
            l=[]
            l.append(name)  # 没有数据就填充--
            l.append(str(i))
            l.append('--')
            l.append('--')
            l.append('--')
            l.append('--')
            l.append('--')
            info_like.append(l)
        for j in range(len(infoes['data']['item'])):  # 可能有多个省录取线,比如提前批,一批,二批等
            l = []
            info = infoes['data']['item'][j]
            name = info['name']
            l.append(info['name'])#存学校名字
            l.append(info['year'])#存年份
            l.append(info['local_type_name'])  # 科类
            l.append(info['max'])#最大录取分数
            l.append(info['average'])#平均分
            l.append(info['min']) #最低分
            l.append(info['proscore']) #省控线
            l.append(info['local_batch_name'])#批次
            info_like.append(l)

        #存文科录取线
        data['local_type_id']=2#更换为文科
        infoes = json.loads(Get_html(url_api,data))
        if len(infoes['data']['item'])==0:
            l=[]
            l.append(name)  # 没有数据就填充--
            l.append(str(i))
            l.append('--')
            l.append('--')
            l.append('--')
            l.append('--')
            l.append('--')
            info_wenke.append(l)
        for j in range(len(infoes['data']['item'])):#可能有多个省录取线,比如提前批,一批,二批等
            l=[]
            info = infoes['data']['item'][j]
            name=info['name']
            l.append(info['name'])  # 存学校名字
            l.append(info['year'])  # 存年份
            l.append(info['local_type_name'])#科类
            l.append(info['max'])   #最大录取分数
            l.append(info['average']) #平均分
            l.append(info['min'])      #最低分
            l.append(info['proscore']) #省控线
            l.append(info['local_batch_name'])#批次
            info_wenke.append(l)

        print(info_like)
        print(info_wenke)

    for i in range(2014,2018):#请求2014-2017的专业录取信息
        # 请求参数信息
        data['year'] = i  # 更换参数年份
        data['school_id'] = id  # 更换学校id
        data['local_type_id'] = 1  # 更换为理科
        data['uri']='/'.join(data['uri'].split('/')[0:-1])+"/special"#更换为请求参数为专业录取线的参数网址
        infoes = json.loads(Get_html(url_api,data))
        #存理科专业信息
        if len(infoes['data']['item']) == 0:
            l = []
            l.append(name)
            l.append(str(i))
            l.append('--')
            l.append('--')
            l.append('--')
            l.append('--')
            l.append('--')
            l.append('--')
            info_like.append(l)
        for j in range(len(infoes['data']['item'])):
            l=[]
            info=infoes['data']['item'][j]
            name=info['name']
            l.append(info['name'])#学校名字
            l.append(info['year'])#年份
            l.append(info['spname'])#专业名称
            l.append(info['local_type_name'])#科类
            l.append(info['average'])#专业平均分
            l.append(info['max'])#最高分
            l.append(info['min'])#最低分
            l.append(info['local_batch_name'])#录取批次
            special_like.append(l)
        #存文科专业录取信息
        data['local_type_id']=2#更换为文科
        infoes = json.loads(Get_html(url_api, data))
        if len(infoes['data']['item']) == 0:
            l = []
            l.append(name)   #没有信息就填充--符号
            l.append(str(i))
            l.append('--')
            l.append('--')
            l.append('--')
            l.append('--')
            l.append('--')
            l.append('--')
            info_like.append(l)
        for j in range(len(infoes['data']['item'])):
            l=[]
            info=infoes['data']['item'][j]
            name=info['name']
            l.append(info['name'])#学校名字
            l.append(info['year'])#年份
            l.append(info['spname'])#专业名称
            l.append(info['local_type_name'])#科类
            l.append(info['average'])#专业平均分
            l.append(info['max'])#最高分
            l.append(info['min'])#最低分
            l.append(info['local_batch_name'])#录取批次
            special_wenke.append(l)
        print(special_like)
        print(special_wenke)
    #*******************保存数据到excel**************************
    print("*************正在写入Excrl数据***************")
    # 创建excel簿指定编码
    file=xlwt.Workbook(encoding='utf-8')
    #创建表 一个表有4个sheet
    print("*************正在写入Excrl理科专业线数据***************")
    table1=file.add_sheet(name+'理科专业线')
    value = ['学校名称', '年份','专业名称','科类', '平均分', '最高分', '最低分', '批次']
    for i in range(len(value)):
        table1.write(0,i,value[i])
    for i in range(len(special_like)):
        for j in range(len(special_like[i])):
            table1.write(i+1,j,special_like[i][j])

    print("*************正在写入Excrl文科专业线数据***************")
    table2 = file.add_sheet(name + '文科专业线')
    value = ['学校名称', '年份', '专业名称', '科类', '平均分', '最高分', '最低分', '批次']
    for i in range(len(value)):
        table2.write(0, i, value[i])
    for i in range(len(special_wenke)):
        for j in range(len(special_wenke[i])):
            table2.write(i + 1, j, special_wenke[i][j])

    print("*************正在写入Excrl理科省控线数据***************")
    table3 = file.add_sheet(name + '理科省控线')
    value = ['学校名称', '年份', '科类', '最高分', '平均分', '最低分', '省控线', '批次']
    for i in range(len(value)):
        table3.write(0, i, value[i])
    for i in range(len(info_like)):
        for j in range(len(info_like[i])):
            table3.write(i + 1, j, info_like[i][j])

    print("*************正在写入Excrl文科省控线数据***************")
    table4 = file.add_sheet(name + '文科省控线')
    value = ['学校名称', '年份', '科类', '最高分', '平均分', '最低分', '省控线', '批次']
    for i in range(len(value)):
        table4.write(0, i, value[i])
    for i in range(len(info_wenke)):
        for j in range(len(info_wenke[i])):
            table4.write(i + 1, j, info_wenke[i][j])

    # ***********指定保存路径******************
    file.save('D:\QQPCMgr(1)\Desktop\高校/' + name + '录取数据.xls')
    print("****************"+name+"所有数据爬取成功"+"*********************")
def main():
    for id in range(30,3000):
        url="https://gkcx.eol.cn/school/"+str(id)
        print(url)
        Get_info(url,id)

if __name__ == '__main__':
    main()

 

评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落凡尘.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值