Python爬虫_城市公交、地铁站点和线路数据采集实例


Posted in Python onJanuary 10, 2018

城市公交、地铁数据反映了城市的公共交通,研究该数据可以挖掘城市的交通结构、路网规划、公交选址等。但是,这类数据往往掌握在特定部门中,很难获取。互联网地图上有大量的信息,包含公交、地铁等数据,解析其数据反馈方式,可以通过Python爬虫采集。闲言少叙,接下来将详细介绍如何使用Python爬虫爬取城市公交、地铁站点和数据。

首先,爬取研究城市的所有公交和地铁线路名称,即XX路,地铁X号线。可以通过图吧公交、公交网、8684、本地宝等网站获取,该类网站提供了按数字和字母划分类别的公交线路名称。Python写个简单的爬虫就能采集,可参看WenWu_Both的文章,博主详细介绍了如何利用python爬取8684上某城市所有的公交站点数据。该博主采集了站点详细的信息,包括,但是缺少了公交站点的坐标、公交线路坐标数据。这就让人抓狂了,没有空间坐标怎么落图,怎么分析,所以,本文重点介绍的是站点坐标、线路的获取。

Python爬虫_城市公交、地铁站点和线路数据采集实例

以图吧公交为例,点击某一公交后,出现该路公交的详细站点信息和地图信息。博主顿感兴奋,觉得马上就要成功了,各种抓包,发现并不能解析。可能博主技术所限,如有大神能从中抓到站点和线路的坐标信息,请不宁赐教。这TM就让人绝望了啊,到嘴的肥肉吃不了。

Python爬虫_城市公交、地铁站点和线路数据采集实例

天无绝人之路,尝试找找某地图的API,发现可以调用,通过解析,能够找到该数据的后台地址。熟悉前端的可以试试,博主前端也就只会个hello world,不献丑了。这是一种思路,实践证明是可以的。

Python爬虫_城市公交、地铁站点和线路数据采集实例

地图API可以,那么通过地图抓包呢?打开某图主页,直接输入某市公交名称,通过抓包,成功找到站点和线路信息。具体抓包信息如下图所示,busline_list中详细列出了站点和线路的信息,其中有两条,是同一趟公交不同方向的数据,略有差别,需注意。找到入口过后,接下来爬虫就要大显身手了。

Python爬虫_城市公交、地铁站点和线路数据采集实例

主要爬取代码如下,其实也很简单,主函数如下。首先需要构建传入的参数,主要的包括路线名称,城市编码,地理范围,缩放尺度。地理范围可以通过坐标拾取器获取,参数经url编码后,发送请求,判断返回数据是否符合要求(注:可能该线路地图上停运或不存在,也可能是访问速度过快,反爬虫机制需要人工验证,博主爬取的时候碰到过,所以后面设置了随机休眠)。接下来,就是解析json数据了。代码中的extratStations和extractLine,就是提取需要的字段,怎么样,是不是很简单。最后,就是保存了,站点和路线分别存储。

def main():
 df = pd.read_excel("线路名称.xlsx",)
 BaseUrl = "https://ditu.amap.com/service/poiInfo?query_type=TQUERY&pagesize=20&pagenum=1&qii=true&cluster_state=5&need_utd=true&utd_sceneid=1000&div=PC1000&addr_poi_merge=true&is_classify=true&"
 for bus in df[u"线路"]:
 params = {
  'keywords':'11路',
  'zoom': '11',
  'city':'610100',
  'geoobj':'107.623|33.696|109.817|34.745'
 }
 print(bus)
 paramMerge = urllib.parse.urlencode(params) 
 #print(paramMerge)
 targetUrl = BaseUrl + paramMerge
 stationFile = "./busStation/" + bus + ".csv"
 lineFile = "./busLine/" + bus + ".csv"
 
 req = urllib.request.Request(targetUrl)
 res = urllib.request.urlopen(req)
 content = res.read()
 jsonData = json.loads(content)
 if (jsonData["data"]["message"]) and jsonData["data"]["busline_list"]:
  busList = jsonData["data"]["busline_list"] ##busline 列表
  busListSlt = busList[0] ## busList共包含两条线,方向不同的同一趟公交,任选一趟爬取
  
  busStations = extratStations(busListSlt)
  busLine = extractLine(busListSlt)
  writeStation(busStations, stationFile)
  writeLine(busLine, lineFile)
  
  sleep(random.random() * random.randint(0,7) + random.randint(0,5)) #设置随机休眠
 else:
  continue

附上博主的解析函数:

def extratStations(busListSlt):
 busName = busListSlt["name"]
 stationSet = []
 stations = busListSlt["stations"]
 for bs in stations:
 tmp = []
 tmp.append(bs["station_id"])
 tmp.append(busName)
 tmp.append(bs["name"])
 cor = bs["xy_coords"].split(";")
 tmp.append(cor[0])
 tmp.append(cor[1])
 wgs84cor1 = gcj02towgs84(float(cor[0]),float(cor[1]))
 tmp.append(wgs84cor1[0])
 tmp.append(wgs84cor1[1])
 stationSet.append(tmp)
 return stationSet

def extractLine(busListSlt):
 ## busList共包含两条线,备注名称
 keyName = busListSlt["key_name"]
 busName = busListSlt["name"] 
 fromName = busListSlt["front_name"]
 toName = busListSlt["terminal_name"]
 lineSet = []
 Xstr = busListSlt["xs"]
 Ystr = busListSlt["ys"]
 Xset = Xstr.split(",")
 Yset = Ystr.split(",")
 length = len(Xset)
 for i in range(length):
 tmp = []
 tmp.append(keyName)
 tmp.append(busName)
 tmp.append(fromName)
 tmp.append(toName)
 tmp.append(Xset[i])
 tmp.append(Yset[i])
 wgs84cor2 = gcj02towgs84(float(Xset[i]),float(Yset[i]))
 tmp.append(wgs84cor2[0])
 tmp.append(wgs84cor2[1])
 lineSet.append(tmp)
 return lineSet

爬虫采集原始数据如下:

Python爬虫_城市公交、地铁站点和线路数据采集实例

以下是某一条公交站点和线路的处理后的数据展示。由于不同的地图商采用不同的坐标系,会有不同程度的偏差,需要坐标纠偏。下一步,博主将详细介绍如何批量将这些站点和坐标进行坐标纠正和矢量化。

Python爬虫_城市公交、地铁站点和线路数据采集实例

Python 相关文章推荐
python使用paramiko模块实现ssh远程登陆上传文件并执行
Jan 27 Python
Python3.6简单操作Mysql数据库
Sep 12 Python
python通过百度地图API获取某地址的经纬度详解
Jan 28 Python
使用实现pandas读取csv文件指定的前几行
Apr 20 Python
对Python发送带header的http请求方法详解
Jan 02 Python
Python数据可视化教程之Matplotlib实现各种图表实例
Jan 13 Python
python单例模式的多种实现方法
Jul 26 Python
opencv调整图像亮度对比度的示例代码
Sep 27 Python
利用Python自动化操作AutoCAD的实现
Apr 01 Python
Python利用for循环打印星号三角形的案例
Apr 12 Python
python实现邮件循环自动发件功能
Sep 11 Python
pytorch分类模型绘制混淆矩阵以及可视化详解
Apr 07 Python
Python tornado队列示例-一个并发web爬虫代码分享
Jan 09 #Python
Python中join函数简单代码示例
Jan 09 #Python
Python中顺序表的实现简单代码分享
Jan 09 #Python
python中set()函数简介及实例解析
Jan 09 #Python
Python中摘要算法MD5,SHA1简介及应用实例代码
Jan 09 #Python
深入了解Python中pop和remove的使用方法
Jan 09 #Python
Python使用smtp和pop简单收发邮件完整实例
Jan 09 #Python
You might like
php debug 安装技巧
2011/04/30 PHP
php+ajax实现无刷新分页
2015/11/18 PHP
PHP实现仿百度文库,豆丁在线文档效果(word,excel,ppt转flash)
2016/03/10 PHP
php实现的XML操作(读取)封装类完整实例
2017/02/23 PHP
PHP CURL与java http使用方法详解
2018/01/26 PHP
IE7中javascript操作CheckBox的checked=true不打勾的解决方法
2009/12/07 Javascript
jquery.validate使用攻略 第二部
2010/07/01 Javascript
JavaScript开发规范要求(规范化代码)
2010/08/16 Javascript
Jquery倒数计时按钮setTimeout的实例代码
2013/07/04 Javascript
JS控件ASP.NET的treeview控件全选或者取消(示例代码)
2013/12/16 Javascript
JavaScript实现按Ctrl键打开新页面
2014/09/04 Javascript
javascript设计模式之对象工厂函数与构造函数详解
2015/07/30 Javascript
js带点自动图片轮播幻灯片特效代码分享
2015/09/07 Javascript
JavaScript脚本库编写的方法
2015/12/09 Javascript
javascript实现去除HTML标签的方法
2016/12/26 Javascript
jquery.cookie.js的介绍与使用方法
2017/02/09 Javascript
vue中eventbus被多次触发以及踩过的坑
2017/12/02 Javascript
JS构造一个html文本内容成文件流形式发送到后台
2018/07/31 Javascript
jquery实现点击弹出对话框
2020/02/08 jQuery
vue中利用iscroll.js解决pc端滚动问题
2020/02/15 Javascript
手动实现vue2.0的双向数据绑定原理详解
2021/02/06 Vue.js
python判断字符串是否包含子字符串的方法
2015/03/24 Python
python调用fortran模块
2016/04/08 Python
Python3.4实现从HTTP代理网站批量获取代理并筛选的方法示例
2017/09/26 Python
PyQt5实现无边框窗口的标题拖动和窗口缩放
2018/04/19 Python
python跳过第一行快速读取文件内容的实例
2018/07/12 Python
Python 从相对路径下import的方法
2018/12/04 Python
pycharm 将python文件打包为exe格式的方法
2019/01/16 Python
Python3.5内置模块之shelve模块、xml模块、configparser模块、hashlib、hmac模块用法分析
2019/04/27 Python
Python使用Opencv实现图像特征检测与匹配的方法
2019/10/30 Python
opencv+python实现鼠标点击图像,输出该点的RGB和HSV值
2020/06/02 Python
全球领先的鞋类零售商:The Walking Company
2016/07/21 全球购物
Luxplus丹麦:香水和个人护理折扣
2018/04/23 全球购物
2019年.net常见面试问题
2012/02/12 面试题
法务专员岗位职责
2014/01/02 职场文书
python 学习GCN图卷积神经网络
2022/05/11 Python