更新時間: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 周一至周日", "評分": , "位址": "北京市懷柔區府前西街2号新悅百貨四樓", "連結": "http://www.dianping.com/shop/70861885", "人均消費": , "評論數量": "261"}
{"種類": "北京菜", "商家名稱": "青龍山莊", "電話": " 13141427145", "營業時間": "全天 周一至周日", "評分": , "位址": "北京市懷柔區懷北鎮河防口村青龍峽道口公交站東800米", "連結": "http://www.dianping.com/shop/68040161", "人均消費": , "評論數量": "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[] + 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, )
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