背景:現(xiàn)有一個需求,需要根據(jù)道路的名稱獲取到道路上所有特征點的經(jīng)緯度,以串聯(lián)成線顯示道路
首先想到的是調(diào)用地圖廠商如高德或者百度現(xiàn)有的webapi,能夠直接返回理想的數(shù)據(jù),但是翻遍了這些廠商的api都沒有發(fā)現(xiàn),搜索之下有篇2020年的帖子說調(diào)用高德隱api可以滿足要求:
http://restapi.amap.com/v3/road/roadname?city=020&key=<用戶的key>&keywords=元崗路
但是實測下來會報錯權(quán)限問題,如圖

說明高德確實是有這個api的,但是因為權(quán)限問題被禁用了,故詢問了一下客服不能調(diào)用的原因或者怎樣可以滿足調(diào)用條件,得到回復(fù)該接口已經(jīng)不對外開放?。?!

那么就沒有辦法了嗎?并不是,既然高德的官網(wǎng)是可以實現(xiàn)這樣子的功能的話,就說明他們是有自己的api在用的,嘗試在高德官網(wǎng)搜索道路

發(fā)現(xiàn)官方是可以實現(xiàn)的,那么我們打開開發(fā)者模式看看他們是怎么請求的,這里不得不說藏的很深!
可以看到在poiinfo接口下有一個看著像是我們想要的數(shù)據(jù):

我們把數(shù)據(jù)拷貝出來看一下

這一個個就很像我們需要的經(jīng)緯度啊,是不是???
但是細(xì)看會發(fā)現(xiàn),這些經(jīng)緯度是被|和_分割開的,如果他倆的作用是一樣的,為啥不用同樣的字符分割?但是我們也不知道人家這樣做的意圖是什么樣子的,所以只能先按照相同的作用做分割,把數(shù)據(jù)分割好之后是這個樣子的:

有那個意思了,導(dǎo)入到項目里面一看,蒙了,連起來是個啥啊,一條路連起來像個蜘蛛網(wǎng),當(dāng)時沒截圖大家可以腦補一下

開玩笑的,這邊項目不方便透露,寫了個demo來按照點的順序展示點,發(fā)現(xiàn)數(shù)據(jù)順序是錯亂的

毫無章法是不是?這指定是有問題的,想來就是點的順序有問題,那么就是數(shù)據(jù)分割的有問題,重新來梳理過:
1、先根據(jù)|分割數(shù)組

發(fā)現(xiàn)了沒,基本上每一段數(shù)據(jù)的起點都是另一段數(shù)據(jù)的終點,intersting,那么有沒有可能根據(jù)這個規(guī)律拼接起來就對了?
2、將對應(yīng)的上的路段首尾相連,理想情況應(yīng)該可以連成一條路段數(shù)據(jù),但是有時候發(fā)現(xiàn)有的路段首尾都沒有相連的其他路段,不要慌張,正常的,如果是雙向道路或者一些奇怪的交叉道路,確實就應(yīng)該就多條連不起來的數(shù)據(jù)的。
3、再把上一步獲得的多條路段數(shù)據(jù)分別用
_分割,再次導(dǎo)入demo中,完美!
這邊查詢的道路不一樣,抱歉,但是就是這么個效果,到這邊我們就拿到了目標(biāo)道路上的所有點
但是這樣手動拼接分割的操作有點過于的反人類
所以寫了個簡易的python腳本處理數(shù)據(jù):
import sys
def main(args):
array = args.split('|')
for i in range(len(array)):
original = array[i]
for j in range(len(array)):
originalArray = original.split('_')
compare = array[j]
compareArray = compare.split('_')
if originalArray[0] == compareArray[len(compareArray) - 1]:
originalNew = originalArray
del originalNew[0]
array[i] = '@@@@@'
array[j] = compare + '_' + '_'.join(originalNew)
while '@@@@@' in array:
array.remove('@@@@@')
result = []
for i in range(len(array)):
locationArray = []
locationStrArray = array[i].split('_')
for item in locationStrArray:
lnglat = item.split(',')
locationArray.append([float(lnglat[0]), float(lnglat[1])])
result.append(locationArray)
print(result)
if __name__ == '__main__':
main(sys.argv[1])
臨時寫的,沒考慮啥性能,莫笑,最終的效果就是傳入從高德官網(wǎng)扒下來的字符串直接輸出二維路線經(jīng)緯度數(shù)組

最后說兩句
該思路僅供個人使用,請勿用作商業(yè)用途
適合少量數(shù)據(jù)研究學(xué)習(xí)使用,如果批量獲取數(shù)據(jù)也不建議直接使用腳本爬取官方網(wǎng)站,給網(wǎng)站增加負(fù)擔(dān),可聯(lián)系商務(wù)洽談?wù){(diào)用事宜