python爬虫系列(一)——城市公交线路及站点数据获取
注:本文章为作者另一站点文章整理城市公交线路及站点数据获取城市公交列表地图解析数据采集1. 数据获取2. 数据解析数据结果城市公交、地铁数据反映了城市的公共交通,研究该数据可以挖掘城市的交通结构、路网规划、公交选址等。但是,这类数据往往掌握在特定部门中,很难获取。互联网地图上有大量的信息,包含公交、地铁等数据,解析其数据反馈方式,可以通过Python爬虫采集,接下来将详细介绍如何使用Python爬
注:本文章为作者另一站点文章整理
城市公交、地铁数据反映了城市的公共交通,研究该数据可以挖掘城市的交通结构、路网规划、公交选址等。但是,这类数据往往掌握在特定部门中,很难获取。互联网地图上有大量的信息,包含公交、地铁等数据,解析其数据反馈方式,可以通过Python爬虫采集,接下来将详细介绍如何使用Python爬虫爬取城市公交线路和站点。
城市公交列表
首先,爬取研究城市的所有公交线路名称,即XX路。可以通过图吧公交、公交网、8684、本地宝等网站获取,该类网站提供了按数字和字母划分类别的公交线路名称。可以通过Python直接抓取页面采集相关公交线路列表。
但是这类站点一般只有线路和站点名称,没有站点的地理坐标。本文重点介绍的是站点坐标、线路的空间位置获取方式。
地图解析
在使用互联网地图(百度、高德)时,搜索如“11路”的时候,能够在地图上显示相应的图形位置,可以发现通过抓包,能成功找到站点和线路信息。具体抓包信息如下图所示,busline_list中详细列出了站点和线路的信息,其中有两条,是同一趟公交不同方向的数据,略有差别,需注意。
数据采集
1. 数据获取
主要爬取代码如下,其实也很简单,主函数如下。
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
首先需要构建传入的参数,主要的包括路线名称,城市编码,地理范围,缩放尺度。地理范围可以通过坐标拾取器获取,参数经url编码后,发送请求,判断返回数据是否符合要求(注:可能该线路地图上停运或不存在,也可能是访问速度过快,反爬虫机制需要人工验证,博主爬取的时候碰到过,所以后面设置了随机休眠)。接下来,就是解析json数据了。代码中的extratStations和extractLine,就是提取需要的字段,怎么样,是不是很简单。最后,就是保存了,站点和路线分别存储。
2. 数据解析
根据需要提取相关信息,代码如下
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
数据结果
采集的公交站点和线路结果如下:
某一公交线路和站点经空间转换和显示如下:
全市公交线路和站点采集结果如图:
更多推荐
所有评论(0)