这是第38篇原创文章
“ 之前有小伙伴后台问到如何抓取公交数据,正好开篇整理一下。”
一般来说公交数据分两块,公交站点+公交线路。
有人可能会说有了公交站点直接连起来不就成了公交线路嘛?
其实不是,公交线路应该是公交站点间的城市道路连接起来形成的,单纯公交站点相连得出的结果与道路的匹配度不高,小尺度还好,遇到长距离公交线就会特别明显。
01
—
有哪些网站可以获取公交数据
一般来说抓数据会有两种常规路径,一是api端口,一是公开网站。
1.1先来讲讲api端口
我记得以前百度地图、高德地图api都开放了相应的端口可以获取公交数据的,包含城市列表、公交站点、公交线路三类,但最近发现已经都关掉了,很可惜。
网上能搜到其他的api端口整理了一下,有以下几个:
haoservice公交线路查询api,全国公交线路导航,免费数据接口
http://www.haoservice.com/docs/23/linename#apicontent
可以看到能直接获取到公交线路,需要key、city、keywords三个参数,key注册账户就能获取,city是待抓取城市名称,keywords是线路名称关键词。
返回的json文本里最主要的就是polyline下的坐标点,连起来就是完整的单条公交线路了。抓取原理并不复杂,拼接出“城市”+“公交线路”的网址,逐个去访问后会得到返回的json文本,再找工具去解析出来所需要的数据,导出列表。
但是超出配额后的资费超贵,免费配额是50次/天,20000次买断是99元,包月最贵的399元也只能10000次/天。
笑园api全国实时公交api接口开放平台
http://dwmm136.cn/app/index.php?i=1&c=entry&do=index&m=mon_yjgz
这个的特点是能获取到实时公交位置,其他大同小异,也能获取城市列表、公交线路,具体可参考文档。
但所有的api端口都受账户配额的限制,超过一定访问次数就需要另外出钱买配额了,对于研究来说不是很划算。
笑园api刚注册的一星会员配额是10000次/天。
阿凡达数据 城市公交,城市公交接口,城市公交api,免费数据接口api
https://www.avatardata.cn/Docs/Api/9b387513-1f95-4810-81db-951023d96b27
也是差不多,阿凡达数据api的配额是1000次/天,比上一个少。
参考文档去抓取就可以了。
1.2再来讲讲公开网站
公开网站的好处就是不受api端口配额的限制,想怎么抓就怎么抓,但是数据抓取和解析就需要更多的精力。
其实类似的网站有很多,这里以8864公交网为例。
8864公交车线路查询_公交线路查询_实时公交查询
https://www.8684.cn/
页面也很好理解,如果是抓全国尺度的话,一般顺序是:
1.2.1首先把页面上全国的城市列表和对应链接抓取下来;
1.2.2再把单个城市拥有的所有公交线路列表抓取下来;
1.2.3最后把单条公交线路下的所有站点数据抓取下来。
基本就完成了,下面简单讲一下步骤。
02
—
如何用FME编写模板?
其实有了思路后就会明确很多,完成后的模板如下。
对应上面分析的三个步骤,逐层递进,最核心的就是三个组件:
httpcaller模块:负责访问网址,返回数据JSONFragmenter模块:负责解析返回的json数据HTMLExtractor模块:负责提取网页中需要的元素和链接(针对非JSON)
其他都属于辅助性插件,比如转换坐标的,8864用的是百度地图经纬度坐标,需要另外找软件或算法去转换成wgs84坐标;比如用ListExploder实现上下层级要素的继承,这一点hawk做的比较好,不像FME是通过炸开list来实现,而是前面出现的字段都是全局参数,后面只需要在“用爬虫转换”中添加原来的字段名就能复用。当然这是后话了。
三个步骤如下:
第一步中用了两个JSONFragmenter是为了分别解析出省份名称和城市名称,对应“广东省”“深圳市”,便于后期分析时做分组。
第二步中最关键就是要把单个城市下按类别分的公交线路列表获取到,我这里用的是“线路分类”,这里也是用到了两次httpcaller,第一次是提取出线路分类下的所有类别及链接,第二次是提取出各类别下的所有公交线路及链接。
第三步,相当于已经拼接好了“省份”+“城市”+“线路分类”+“公交列表”的url链接表,直接访问去获取单条线路的公家站点就OK了。
上半边出来的是公交站点,下半边出来的是简单的把公交站点连起来的公交线,不是很准,仅参考用。
有些小伙伴可能不知道数据在哪里,我们以上海市其中一条公交线路举例。
01线公交车路线
https://shanghai.8684.cn/x_ccc80acf
打开F12审查模式后刷新页面,在network下xhr中可以看到公交站点的数据都放在这里,返回的也是标准的JSON文本,解析起来也挺简单。
其他都是常规操作。
03
—
如何把数据写入MongoDB数据库?
因为涉及全国尺度的公交站点数据,数据量还挺大的。
如果用往常的写入txt、csv等文件的方式很容易崩,所以推荐用FME挂在MongoDB数据库上,一边抓取一边入库,避免一崩就全部数据都没了。
具体设置,以FME2019为例,写模块中选择MongoDB,添加数据库连接,上面的名称其实是随意写的,主要是FME中自己做区分的;关键是下面的uri怎么写呢?
我是参考菜鸟教程设置的。
MongoDB 连接 | 菜鸟教程
https://www.runoob.com/mongodb/mongodb-connections.html
连接默认数据库是:
mongodb://localhost
连接默认数据库下面的test数据库是:
mongodb://localhost/test
带账号密码连接默认数据库是:
mongodb://fred:foobar@localhost
基本常用的就是这几个了,其他的可以点开连接自己研究下。
抓完全国的公交站点数据大概是122万+个,涉及488个城市,但后续还需要根据站点名称做去重,因为很多公交线路的站点是共用的。
大概的分布如下,标准的黑河腾冲线分布,可以看到挺多散布在外围的点应该是经纬度缺失的,后续可通过国界筛选掉,最后的可视化用GIS或者mapbox做都行,参考 可视化 | 如何按密度可视化公交线路?
以上。
来都来了,关注一下
历史推荐:
FME | 如何提取地形图dwg中的高程点块参照信息?
FME | POI数据如何聚合到网格尺度以实现数据降维?
交流 | FME在规划项目中的实证应用
解读 | 如何用FME爬取和分析腾讯人口迁徙数据
FME入门 | 如何快速提取地块内建筑量并计算容积率?
FME入门 | FME这么好用到底能在规划里做什么?