轻松实现全国高校地理位置数据爬取

一个城市的历史底蕴,不光可以从经济、文化和人文景点,还可以从高校的数量可以看出来。所以,今天就来试试如何爬取全国高校的分布数据。

天要爬取的网站是:中国教育在线,对应的网址是:https://gkcx.eol.cn/school/search

因为对应的是位置点,所以最主要的应该是经纬度点坐标数据。

但是在该网站中无法获取到高校的经纬度数据,所以在文末会教你利用地址解析的方式获取到经纬度坐标。

以下是正文:

爬虫流程

打开对应网址后,F12 打开开发者工具,切换到 Network 选项卡下的 XHR

通过在网页中点击 上一页下一页 按钮可以发现有如下的请求:

多次点击后可以发现对应的只是请求参数 page 在发生变化

对应每一页的请求参数 page 对应的该页在整个数据集中所处的位置

而总的数据集个数在每个请求的 response 中可以获取到

从而通过 总个数/每页个数=页面数 确定总的请求次数

在每次请求的响应中可以看到返回的数据有很多,包括:高校地址、所在城市、地区、直属机构、类别、是否双一流 以及对应的浏览次数等数据

综上,前期的数据爬取中,总体流程如下:

  • 获取总记录数,计算请求次数

  • 遍历请求次数,构造每一次请求的 url

  • 解析并获取数据

最后,通过百度地图反向解析高校的经纬度数据,这个在文末会介绍到

爬虫实现

基于上面的爬虫流程,依次进行爬虫的代码实现

首先是获取到总记录数,

url = 'url'
res = requests.post(url, headers={'User-Agent': get_ua()})
data = json.loads(res.text)

# 解析数据
if data["message"] == '成功':
    size = data["data"]["numFound"]

由于每次请求返回的数据是 JSON 格式,通过上述方式可以直接获取到总记录数

从而可以很方便的计算出总请求次数:

# 计算请求次数
page_cnt = int(size/page_size) if size%page_size==0 else int(size/page_size)+1
print('一共{0}页数据'.format(page_cnt))

其次, 遍历请求次数,构造每一次的请求 url

其实主要是更新下标 index

for index in range(1, page_cnt+1):
    print('正在爬取第 {0}/{1} 页数据'.format(index, page_cnt))
    url = 'https://api.eol.cn/gkcx/api/?access_token=&admissions=&central=&department=&dual_class=&f211=&f985=&is_doublehigh=&is_dual_class=&keyword=&nature=&page={0}&province_id=&ranktype=&request_type=1&school_type=&signsafe=&size=20&sort=view_total&top_school_id=[2941]&type=&uri=apidata/api/gk/school/lists' \
    .format(index)
    
    res = requests.post(url, headers={'User-Agent': get_ua()})
 data = json.loads(res.text)

最后是解析每一页的数据

由于数据是 JSON 格式,可以很方便的通过 DataFrame 进行转换

# 解析数据
if data["message"] == '成功':
    df_data = pd.DataFrame(data["data"]["item"])
    df_result = df_result.append(df_data)

最后对整体数据进行保存即可。

地址解析,匹配经纬度

地址解析主要是通过百度开发者平台,对高校的地址进行解析

平台提供的接口是这样的:

对应的,我们将每个 高校的地址 作为 query 参数,将 省份+城市 作为 region 参数,设置 tag 为 高等院校,构造访问 url

相应的代码如下:

df_data = pd.read_csv(filepath, encoding='gbk')
for row_index, data_row in df_data.iterrows():
    region = data_row['province_name']+data_row['city_name']
    query = data_row['name']
    url = 'http://api.map.baidu.com/place/v2/search?query={0}&tag={1}&region={2}&output=json&ak={3}'.format(query, "高等院校", region,  '你的key')

最后是对每次的请求进行解析,获取到百度地图返回的经纬度数据

思路比较简单,相应代码如下:

res = requests.get(url, headers={'User-Agent': get_ua()})
data = json.loads(res.text)
if len(data["results"]) > 0:
    df_data = pd.DataFrame(data["results"])
    df_data['lat'] = df_data['location'].apply(lambda x: x['lat'])
    df_data['lng'] = df_data['location'].apply(lambda x: x['lng'])
    
    # 返回数据
    bd_lng = df_data.loc[0, "lng"]
    bd_lat = df_data.loc[0, "lat"]

个人开发者在百度开放平台每天有 3w 次地点检索的免费配额,在使用的时候可以注意下

本次的高校数据集大概不到 3000 条,建议在运行之前可以先写好测试 demo

最终数据及效果

爬取到的高校数据共 2827 条,每个数据 46 个字段

部分数据截图如下:

将高校经纬度打在地图上,分布是这样的:

这份数据和目前教育部公布的数据还是有一些小小的出入,但是在可容忍范围之内,所以误差可以暂时忽略。

END -



本文为转账分享&推荐阅读,若侵权请联系后台删除
-------------------------------------
长按识别下方二维码,并关注公众号

1.回复“PY”领取1GB Python数据分析资料

2.回复“BG”领取3GB 名企数据分析报告
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值