1. 程式人生 > >python利用百度API進行地理編碼(將地名轉換為經緯度資訊)

python利用百度API進行地理編碼(將地名轉換為經緯度資訊)

更新時間:2018-3-28
更新內容:優化部分程式碼,新增mongodb部分的內容

本文章通過講解如何在百度地圖API申請金鑰,然後在python中呼叫API介面將自有資料中的地名轉換為經緯度座標。

執行環境: python3


一、註冊金鑰

在百度地圖API上相關位置的展現是以經緯度為基礎的。要使用百度地圖介面需要註冊百度地圖API以獲取免費的金鑰,才能完全使用該API。登入網址:http://lbsyun.baidu.com/
首頁點選申請金鑰按鈕,經過填寫個人資訊、郵箱註冊等,成功之後在開放平臺上點選“建立應用”,填寫相關資訊,應用名稱可隨意填寫,應用型別根據自己需要進行設定,若是做安卓開發則選擇Android SDK,本應用中因為是通過瀏覽器端進行呼叫,所以選擇瀏覽器端

。在這裡特別說明的是,在IP白名單框裡,如果不清楚自己的IP地址,最好設定為:0.0.0.0/0,雖然百度提醒它會有洩露使用的風險,但是有時候你把你自己的IP地址輸進去可能也不行。提交後,在你建立應用的訪問應用(AK)那一欄就是你的金鑰。

二、利用申請好的金鑰獲取經緯度座標

註冊好金鑰後就可以使用百度Web服務API下的Geocoding API介面來獲取你所需要地址的經緯度座標並轉化為json結構的資料,開發文件連結為Geocoding API,該文件中有一些引數的說明,如果需求和本文不太一致,可前往該頁面瞭解每個引數的作用並進行修改以獲取需要的效果。
下面是根據地址獲取經緯度的函式。傳入地名,返回緯度,經度

import json
from urllib.request import urlopen, quote
import requests
def getlnglat(address):
    url = 'http://api.map.baidu.com/geocoder/v2/'
    output = 'json'
    ak = '申請好的金鑰' # 瀏覽器端金鑰
    address = quote(address) # 由於本文地址變數為中文,為防止亂碼,先用quote進行編碼
    uri = url + '?' + 'address=' + address  + '&output='
+ output + '&ak=' + ak req = urlopen(uri) res = req.read().decode() temp = json.loads(res) lat = temp['result']['location']['lat'] lng = temp['result']['location']['lng'] return lat, lng

三、讀取資料批量獲取經緯度

{"種類": "火鍋", "商家名稱": "沸爐火鍋·地道的川味火鍋(懷柔...", "電話": "  010-60686895", "營業時間": "10:00-21:00 週一至週日", "評分": 9.2, "地址": "北京市懷柔區府前西街2號新悅百貨四樓", "連結": "http://www.dianping.com/shop/70861885", "人均消費": 96, "評論數量": "261"}
{"種類": "北京菜", "商家名稱": "青龍山莊", "電話": "  13141427145", "營業時間": "全天 週一至週日", "評分": 7.8, "地址": "北京市懷柔區懷北鎮河防口村青龍峽道口公交站東800米", "連結": "http://www.dianping.com/shop/68040161", "人均消費": 92, "評論數量": "15"}

本文中讀取的資料為上述型別的json資料,讀取每一行資料到一個字典中,將字典中的地址資料傳給上文中的引數,獲取返回的經緯度,並寫入字典中,儲存為新的資料。
完整程式碼為:

#-*-coding:utf-8-*-
# getlonlat.py
# from: mamq
# run: python3 getlonlat.py
from urllib.request import urlopen, quote
from pymongo import MongoClient
import json
import codecs
import sys
import os

path = sys.path[0] + os.sep

def getlnglat(address):
    """根據傳入地名引數獲取經緯度"""
    url = 'http://api.map.baidu.com/geocoder/v2/'
    output = 'json'
    ak = '申請好的金鑰' # 瀏覽器端金鑰
    address = quote(address) 
    uri = url + '?' + 'address=' + address  + '&output=' + output + '&ak=' + ak 
    req = urlopen(uri)
    res = req.read().decode() 
    temp = json.loads(res)
    lat = temp['result']['location']['lat']
    lng = temp['result']['location']['lng']
    return lat, lng

def jsondump(outfilename, dic):
    """傳入儲存路徑和字典引數,儲存資料到對應的檔案中"""
    with codecs.open(path + outfilename + '.json', 'a', 'utf-8') as outfile:
        json.dump(dic, outfile, ensure_ascii=False)
        outfile.write('\n')

def convertfile(filename):
    file = codecs.open(path + filename, 'r', encoding='utf-8')
    outfilename = 'loc' + filename
    for line in file:
        dic = json.loads(line.strip())
        address = dic['地址']
        dic['lat'], dic['lng'] = getlnglat(address)
        jsondump(outfilename, dic)

def convertmongodb(host, dbname, collname):
    '''連線mongodb, 並根據其位置欄位得到其座標資訊,進而更新資料庫'''
    client = MongoClient(host, 27017)   
    db = client[dbname]
    collection = db[collname]
    for dic in collection.find():
        dic['lat'], dic['lng'] = getlnglat(dic['地址'])
        collection.save(dic) # 更新資料,並覆蓋相同_id的記錄
    print (dic)

if __name__ == '__main__':
    filename = '/home/mamq/test.json'
    # convertfile(filename)
    host = '192.168.1.101' # 需要連線的資料庫所在ip
    dbname = 'landPlan'
    collname = 'xian'
    convertmongodb(host, dbname, collname)

參考資料:
[1]:Geocoding API:Web服務API