天天看點

高德地圖之根據矩形範圍爬取範圍内的分類POI資料

目前代碼已經做了更新處理,參見:

http://www.mapboxx.cn/article/poi-pology/

下面的可以不用看啦。。。

     之前寫了一篇在城市範圍内根據關鍵字爬取POI資料的部落格,由于一個城市的POI資料量太大,高德地圖接口容易傳回錯誤資料,是以有個比較好的辦法就是借助高德地圖POI搜尋中根據多邊形範圍或矩形範圍搜尋POI資料,具體分為兩個步驟:其一是将城市分為多個小矩形(得到左上和右下兩個頂點的坐标即可);二是根據得到的矩形坐标調用高德地圖WEB API得到資料解析即可。這篇文章主要是記錄根據矩形範圍搜尋POI的流程,至于如何切分城市為矩形,我也還沒弄過,可以自行百度搜尋解決。

     先看下爬取到的資料吧:

高德地圖之根據矩形範圍爬取範圍内的分類POI資料

    高德矩形搜尋的API文檔參見這裡:https://lbs.amap.com/api/webservice/guide/api/search#polygon。這裡給出一個具體的示例:

http://restapi.amap.com/v3/place/polygon?polygon=116.80708,31.449926,117.510206,32.247823&key=c5304f29d1a11f14c4fb29854a831ef0&extensions=all&offset=25&page=1&keywords=%E5%A4%A7%E5%AD%A6
           

參數說明:

               polygon:多邊形邊界範圍(或者是矩形左上和右下兩個頂點坐标)

               key : 高德地圖web api申請的密鑰key

               extensions :此項預設傳回基本位址資訊;取值為all傳回位址資訊、附近POI、道路以及道路交叉口資訊。

               offset :分頁的頁大小

               page:請求的頁碼

其餘的具體參數介紹詳見文檔說明。

可以在浏覽器看到示例URL傳回的資料。剩餘的就是循環擷取資料,然後解析入庫的事情了,挺簡單的。這裡就直接貼上代碼了:

from urllib import request
import json
import xlwt
import transCoordinateSystem as transCoordinateSystem


# TODO
amap_web_key = '申請的密鑰'  # 高德地圖官網申請的Web API KEY
filename = r'C:\\Users\\hgvgh\\Desktop\\hehe.xls'  # 爬取到的資料寫入的EXCEL路徑

# 多邊形邊界集合:
'''
規則:經度和緯度用","分割,經度在前,緯度在後,坐标對用"|"分割。         
多邊形為矩形時,可傳入左上右下兩頂點坐标對;其他情況下首尾坐标對需相同。
'''
polygon_list = ['104.01991721224772,30.675517485068525|104.04335935135217,30.69685368121003|104.10490633670742,30.681154431514038|104.10713973787826,30.642336396516658|104.05432192815479,30.623029707583|104.02008888045066,30.64717739010567|104.01991721224772,30.675517485068525']

# POI分類集合, 多個類型用豎線 | 分割;
type_list = '140000' #|060402|060403|060404|060405|060406|060407|060408|060409|060411|060413|060414|060415|060100|060101|060102|060103'


# 輸出坐标系:0,預設高德坐标系,1,百度坐标系,2,WGS84坐标系
output_coordinate = 2



poi_search_url = "http://restapi.amap.com/v3/place/polygon"  # URL

offset = 25  # 分頁請求資料時的單頁大小


# 根據矩形坐标擷取poi資料
def getpois(polygon, type_list):
    i = 1
    current_polygon_poi_list = []
    while True:  # 使用while循環不斷分頁擷取資料
        result = getpoi_page(polygon, i, type_list)
        result = json.loads(result)  # 将字元串轉換為json

        # print('第', str(i),'頁,結果',result)

        if result['status'] is not '1':  # 接口傳回的狀态不是1代表異常
            print('======爬取錯誤,傳回資料:' + result)
            break
        pois = result['pois']
        if len(pois) < offset:  # 傳回的資料不足分頁頁大小,代表資料爬取完
            current_polygon_poi_list.extend(pois)
            break
        current_polygon_poi_list.extend(pois)
        i += 1
    print('===========目前polygon:', polygon, ',爬取到的資料數量:', str(len(current_polygon_poi_list)))

    return current_polygon_poi_list


# 單頁擷取pois
'''
http://restapi.amap.com/v3/place/polygon?polygon=116.80708,31.449926,117.510206,32.247823&key=c5304f29d1a11f14c4fb29854a831ef0&extensions=all&offset=5&page=1
'''


def getpoi_page(polygon, page, type_list):

    print(polygon)
    req_url = poi_search_url + "?key=" + amap_web_key + '&extensions=all&polygon=' + polygon + '&offset=' + str(
        offset) + '&types=' + type_list + '&page=' + str(page) + '&output=json'
    data = ''
    with request.urlopen(req_url) as f:
        data = f.read()
        data = data.decode('utf-8')
        print(data)
    return data


# 資料寫入excel
def write_to_excel(poilist, filename):
    # 一個Workbook對象,這就相當于建立了一個Excel檔案
    book = xlwt.Workbook(encoding='utf-8', style_compression=0)
    sheet = book.add_sheet('0', cell_overwrite_ok=True)
    # 第一行(列标題)

    sheet.write(0, 0, 'id')
    sheet.write(0, 1, 'name')
    sheet.write(0, 2, 'lon')
    sheet.write(0, 3, 'lat')
    sheet.write(0, 4, 'address')
    sheet.write(0, 5, 'pname')
    sheet.write(0, 6, 'cityname')
    sheet.write(0, 7, 'adname')
    sheet.write(0, 8, 'type')
    for i in range(len(poilist)):
        sheet.write(i + 1, 0, poilist[i]['id'])
        sheet.write(i + 1, 1, poilist[i]['name'])
        lon = float(str(poilist[i]['location']).split(",")[0])
        lat = float(str(poilist[i]['location']).split(",")[1])

        if output_coordinate == 1:
            coordinates = transCoordinateSystem.gcj02_to_bd09(lon, lat)
            lon, lat = coordinates[0], coordinates[1]

        if output_coordinate == 2:
            coordinates = transCoordinateSystem.gcj02_to_wgs84(lon, lat)
            lon, lat = coordinates[0], coordinates[1]

        sheet.write(i + 1, 2, lon)
        sheet.write(i + 1, 3, lat)
        sheet.write(i + 1, 4, poilist[i].get('address'))
        sheet.write(i + 1, 5, poilist[i].get('pname'))
        sheet.write(i + 1, 6, poilist[i].get('cityname'))
        sheet.write(i + 1, 7, poilist[i].get('adname'))
        sheet.write(i + 1, 8, poilist[i]['type'])

    book.save(filename)

    '''
        #xls檔案轉換為CSV檔案:
        data_xls = pd.read_excel('1.xlsx', index_col=0)
        data_xls.to_csv('1.csv', encoding='utf-8')
    '''
print(output_coordinate == 2)

all_poi_list = []  # 爬取到的所有資料

for polgon in polygon_list:
    polygon_poi_list = getpois(polgon, type_list)
    all_poi_list.extend(polygon_poi_list)

print('爬取完成,總的數量', len(all_poi_list))
write_to_excel(all_poi_list, filename)
print('寫入成功')
           

自己運作的話需要修改的地方都在代碼上方位置,具體的說明在代碼中已有注釋。

有問題可以加入地圖資料爬取交流群:626697156