Python爬虫——城市公交、地铁站点和线路数据采集!

优采云 发布时间: 2020-08-10 17:32

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

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

  

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

  

  

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

  

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

  

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

  

   1 def main():

2 df = pd.read_excel("线路名称.xlsx",)

3 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&"

4 for bus in df[u"线路"]:

5 params = {

6 'keywords':'11路',

7 'zoom': '11',

8 'city':'610100',

9 'geoobj':'107.623|33.696|109.817|34.745'

10 }

11 print(bus)

12 paramMerge = urllib.parse.urlencode(params)

13 #print(paramMerge)

14 targetUrl = BaseUrl + paramMerge

15 stationFile = "./busStation/" + bus + ".csv"

16 lineFile = "./busLine/" + bus + ".csv"

17

18 req = urllib.request.Request(targetUrl)

19 res = urllib.request.urlopen(req)

20 content = res.read()

21 jsonData = json.loads(content)

22 if (jsonData["data"]["message"]) and jsonData["data"]["busline_list"]:

23 busList = jsonData["data"]["busline_list"] ##busline 列表

24 busListSlt = busList[0] ## busList共包含两条线,方向不同的同一趟公交,任选一趟爬取

25

26 busStations = extratStations(busListSlt)

27 busLine = extractLine(busListSlt)

28 writeStation(busStations, stationFile)

29 writeLine(busLine, lineFile)

30

31 sleep(random.random() * random.randint(0,7) + random.randint(0,5)) #设置随机休眠

32 else:

33 continue

  附上博主的解析函数:

   1 def extratStations(busListSlt):

2 busName = busListSlt["name"]

3 stationSet = []

4 stations = busListSlt["stations"]

5 for bs in stations:

6 tmp = []

7 tmp.append(bs["station_id"])

8 tmp.append(busName)

9 tmp.append(bs["name"])

10 cor = bs["xy_coords"].split(";")

11 tmp.append(cor[0])

12 tmp.append(cor[1])

13 wgs84cor1 = gcj02towgs84(float(cor[0]),float(cor[1]))

14 tmp.append(wgs84cor1[0])

15 tmp.append(wgs84cor1[1])

16 stationSet.append(tmp)

17 return stationSet

18

19 def extractLine(busListSlt):

20 ## busList共包含两条线,备注名称

21 keyName = busListSlt["key_name"]

22 busName = busListSlt["name"]

23 fromName = busListSlt["front_name"]

24 toName = busListSlt["terminal_name"]

25 lineSet = []

26 Xstr = busListSlt["xs"]

27 Ystr = busListSlt["ys"]

28 Xset = Xstr.split(",")

29 Yset = Ystr.split(",")

30 length = len(Xset)

31 for i in range(length):

32 tmp = []

33 tmp.append(keyName)

34 tmp.append(busName)

35 tmp.append(fromName)

36 tmp.append(toName)

37 tmp.append(Xset[i])

38 tmp.append(Yset[i])

39 wgs84cor2 = gcj02towgs84(float(Xset[i]),float(Yset[i]))

40 tmp.append(wgs84cor2[0])

41 tmp.append(wgs84cor2[1])

42 lineSet.append(tmp)

43 return lineSet

  

  爬虫采集原创数据如下:

  

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

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线