之前写过1篇如何基于8684公交查询网站获取城市公交网络数据的文章,但获取到的公交网络数据里是不包含经纬度信息的。

近日,有小伙伴咨询我,怎样把公交线路和各站点的经纬度信息也同步获取到,从而进行一些可视化展示。

周末闲来无事,就基于高德地图简单研究了一下,并把实现过程分享出来。

1 获取公交线路名称集合

想要获取整个城市的公交线路数据,第一步是先拿到城市公交线路的名称集合,然后再基于线路名去请求各个线路的详细信息。

这一过程可以基于8684公交查询网站来实现,具体过程可参见我之前的博文。


代码如下:

def get_busline_names(city_name):request_url = "https://%s.8684.cn" %(city_name)init_href = "/list1"start_html = requests.get(request_url + init_href)soup = BeautifulSoup(start_html.text, 'lxml') #以lxml的方式解析html文档pre_list = soup.find('div', class_='tooltip-body cc-content-tooltip').find('div', class_='tooltip-inner').find_all('a')busline_names = list()for pre in pre_list:# 拼接出pre前缀公交线路的请求urlurl = request_url + pre['href']pre_html = requests.get(url)pre_soup = BeautifulSoup(pre_html.text, 'lxml')busline_names_a = pre_soup.find('div', class_='list clearfix').find_all('a')for busline_name_a in busline_names_a:busline_names.append(busline_name_a.get_text())return busline_names

2 获取各个公交线路详情

8684公交查询网站是不包含公交网络的经纬度数据的,要获取经纬度数据,只能借助于地图应用来获取,比如高德地图。

获取高德地图数据,基本有3种途径:

  • 直接调用高德地图开放出来的Web API

简单易用,可以快速上手。但该途径需要注册高德地图账号,并申请AK,且有日调用次数的限制。

同时,可能某些数据未提供相应接口。

  • 高德地图的JS API

JS API Demo示例里提供了很多数据接口,可以通过浏览器开发者工具抓包分析出后台的数据http服务接口,并得到请求的构建方法,然后模拟发送请求。

  • 直接分析高德地图的检索请求,直接调用相关服务接口

该种方法需要在高德地图上构建好检索请求,通过浏览器开发者工具抓包分析出后台的数据http服务接口,并得到请求的构建方法,然后模拟发送请求。

首先看一下高德地图的Web API页面:


发现高德地图并没有提供公交线路检索的Web API。

有个POI检索倒是可以试试,但尝试了一下之后,发现也不能满足我们的需求,比如关键字给"1路",其返回的均是1路公交线上各个站点的信息,并没有线路信息。可以看出,POI Web API关注的更多是点信息。

接着尝试第2种途径:


可以看到,JS API里提供了公交线路检索的接口。

下面就是抓包分析请求了,老规矩,打开浏览器的开发者工具:


很容易就找到了目标接口,同时观察接口返回数据,其中的polyline字段就是线路的经纬度集合,而busstops字段是该线路各个站点的信息,其中也包含了站点的经纬度信息。

接着看一下该接口的请求信息(参数、headers等):


一般来讲,参数和headers里面的大部分参数均是可选参数,我们可以尝试去掉某些参数,然后观察请求是否仍然可以正常返回。

逐步分析出该请求的headers必须包含下述两项:

headers = {'Host': 'restapi.amap.com','Referer': 'https://lbs.amap.com/'
}

请求参数如下:

params = {"s": "rsv3","key": "******","city": "******","pageIndex": "1","offset": "20","extensions": "all","keywords": "1路"
}

city参数代表城市名称或者citycode,offset代表每次请求单页包含的元素数,extensions配置必须为all的时候才会有经纬度数据,keywords配置传入公交线路名称。

不应该传入1条公交线路名称,只返回1个结果吗,为啥还要配置offset呢?

首先是因为,同一个公交线路名称一般会有正、反2个方向,同时,高德地图在检索的时候,采用的是模糊搜索策略,比如你搜索"1路",“11路”、"121路"等可能也会在返回集合里,其返回的时候会根据匹配得分进行排序,一般取前2个元素(正好对应线路的2个方向)。

分析完毕,下面代码实现一下:

def get_busline_info_amap(busline_names, citycode, key, col_sink, time_delay):request_url = "https://restapi.amap.com/v3/bus/linename"params = {"s": "rsv3","key": key,"city": citycode,"pageIndex": "1","offset": "20","extensions": "all","keywords": "1路"}headers = {'Host': 'restapi.amap.com','Referer': 'https://lbs.amap.com/',}# 线路的set集合,保证线路无重复buslines_loaded = set()count = 0for line_name in busline_names:params["keywords"] = line_nameres = requests.get(url=request_url, headers=headers, params=params).json()if res["status"] == "1":for busline in res["buslines"]:busline_name = busline["name"]# 若该线路未请求过,则创建请求if busline_name not in buslines_loaded:buslines_loaded.add(busline_name)col_sink.insert_one(busline)count += 1print("第%d条公交线路%s采集完成!" % (count, busline_name))# 休眠time_delay秒,防止对高德服务器太高压力time.sleep(time_delay)# 主函数
if __name__ == '__main__':key = "******"# 接口请求之间的间隔time_delay = 0.01city_name = "北京市"city_py = "beijing"db_name = 'web_map'col_name = 'buslines_' + city_py# MongoDB数据库所在的服务器host = '******'port = 27017# 获取mongodb的表句柄col = mongo_util.get_col(db_name, col_name, host, port)busline_names = get_busline_names(city_py)# 获取北京市公交网络数据get_busline_info_amap(busline_names, city_name, key, col, time_delay)

点击运行,数据哗啦啦入库,任务完成!


第3种途径的实现方式跟第2种步骤基本一致,区别就是请求的构建方式略有不同,此处不再赘述,读者可自行实践。

需要注意的是: 高德地图返回的经纬度是火星坐标系,在进行可视化展示时,若GIS瓦片地图是WGS-84或者百度坐标系时,需要将坐标转换到对应坐标系,否则会出现线路与底图无法对齐的问题。

本文到此结束,谢谢阅读!

一文教会你如何基于高德地图获取城市公交网络数据(包含经纬度)相关推荐

  1. 从高德地图获取城市公交线路+站点

    公交线路+站点 在研究城市公共交通问题上,地面的公交网络研究算是很重要的一块,因此获取整个城市的公交线路及其站点的所有数据是非常重要的!但令人高兴的是,有关这些数据的获取其实是很方便快捷的,因为目前的 ...

  2. 基于高德地图实现的公交线路查询功能

    高德地图支持公交线程查询功能.线上示例; 线上示例说明 接口返回的数据结构: path和via_stops字段详情: ... path: [{Q: 39.97741, R: 116.397880999 ...

  3. 基于高德地图根据地址名称返回对应的经纬度

    在吹水之前,首先先感谢阿里巴巴所提供的高德地图服务,没有阿里巴巴,那接下来的逼我也装不了. 写这篇博客的缘由,原因是我闲的慌,想搞点事情.因为工作中,有这么一个需求,需要根据一系列的具体地址,返回所对 ...

  4. 在vue中使用高德地图获取坐标与地址信息(包含点击+搜索)

    首先 注册登陆高德地图 https://lbs.amap.com/ 划过头像里面有个应用管理点开 进入到应用管理打开我的应用 选择创建应用 然后按照要求填写内容,切记一定要选择web端(JS API) ...

  5. 基于高德地图的描点操作,监听地图缩放,展示合理数量的marker

    原文:基于高德地图的描点操作,监听地图缩放,展示合理数量的marker 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/lx583274568/art ...

  6. 只用一个marker 替换 高德_Android基于高德地图完全自定义Marker的实现方法

    前言 相信做地图社交类APP开发的大家都知道,一般情况下,为了整体的美观和用户体验度,我们需要定制化Marker的样式.本文中实现的方式都是基于高德地图的,百度地图也类似,大家可以照葫芦画瓢,废话不多 ...

  7. python交通调查数据处理_GitHub - unlimitbladeworks/traffic-monitor: 基于高德地图的交通数据分析...

    traffic-monitor(基于高德地图的交通数据分析) 设计需求在于每天上班早高峰期,每次都提前出门,虽然有地图可以实时查看路况,但是再过一阵时间 就会异常的堵车如果通过数据监控分析每天指定路段 ...

  8. 基于高德地图JsAPI进行浏览器精确定位,实现手机端考勤打卡功能

    前言: 由于项目需求需要在项目中实现手机端(基于网页)考勤打卡功能,最初考虑使用H5自身定位功能,但尝试过后,效果很不稳定.然后尝试使用百度地图JsAPI,百度家的稳定倒是很稳定,没想到的是定位位置和 ...

  9. vue中基于echarts和基于高德地图的两种地图下钻与上浮方式

    ** vue中基于echarts和基于高德地图的两种地图下钻与上浮方式 ** 基于echarts的地图下钻与上浮(浙江省为例) 第一步:在<template>中构建承载echarts的do ...

  10. 基于高德地图实现可编辑的电子围栏功能【多边形围栏】

    上次基于高德地图实现了圆形围栏功能,但限于实地使用场景,故近期重新升级到多边形电子围栏,经过反复测验及优化,目前可正常使用. 1.主要功能: 多边形围栏的CURD: 自定义变数,形状: 自动计算变数及 ...

最新文章

  1. Pytorch中的广播机制
  2. 通过访问列表实现MAC地址绑定,实现包过滤
  3. 经典C语言程序100例之十五
  4. 用条件运算符编写java程序,使用条件运算符的奇怪java行为。这是一个错误吗?...
  5. mac sublime java_Mac环境下使用SublimeText写Java代码
  6. 这7个问题,软件测试面试必问!!!
  7. 风格迁移篇----艺术风格转换的内容与风格解构
  8. 计算机操作系统期末考试大全,计算机操作系统期末考试试题含答案
  9. 小米为何要死磕某国产手机企业?这是多年被压迫下的反击
  10. vue+mars3d 组件封装与应用 +简单示例
  11. centos7切换图像界面和dos界面
  12. 2022年6月的顶级黑客
  13. SPA 项目 之 后台接口文档
  14. 打不开计算机 在任务栏里显示,电脑下方的任务栏不显示怎么办 电脑任务栏不显示解决方法【图文】...
  15. Linux目录与管理
  16. Python、OpenCV实现的电脑远程拍照控制系统,照片并以web形式发布
  17. 点击按钮自动拨打电话
  18. 文献笔记|自我管理相关 self- regulation
  19. 用计算机求a的绝对值,计算机概论A卷
  20. 厦门大学 数据库实验室(林子雨)

热门文章

  1. poi填充word,动态生成表格+LibreOffice转成pdf
  2. SPI通信协议学习笔记
  3. 【暂更】分享亲测有效的那些实用「神器」!(网站/软件/小技巧)
  4. 矩阵连乘问题算法思想_动态规划之矩阵连乘问题
  5. Java小峰宿舍管理系统_基于JAVA的宿舍管理系统
  6. 2022年道路运输企业安全生产管理人员考题及答案
  7. 淘宝618超级喵运会怎么玩?超级喵运会整体活动攻略来了
  8. 内网远程协助工具_分享几个常用的免费远程软件
  9. 【POJ 1838 --- Banana】
  10. IOS OpenGL ES GPUImage 图像 XYDerivative 边缘检测 GPUImageXYDerivativeFilter