根據IP定位城市名稱/經緯度
阿新 • • 發佈:2019-02-07
最近想統計下公司使用者在中國地圖上的分別情況,但使用者登錄檔中填寫的單位資訊比較混亂,提取省份、城市名稱較困難,最後決定用ip地址來查詢對應資訊。搜尋到兩種常用的方式:
- 採用純真資料庫qqwry.dat,傳入ip返回省+城市名稱,無經緯度資訊;缺點:返回的地址資訊太詳細,有的能定位到小區名稱,不利於歸類統計數量;優點:qqwry.dat資料庫更新快且地址資訊更具體,部分能定位到縣或小區。
- 利用百度的IP定位API介面,傳入IP傳送get請求,返回地址資訊;缺點:請求耗時較多;優點:返回資訊為json格式,且能提取到省、城市、經緯度等更多獨立資訊。
1、純真資料庫qqwry.dat:
首先需要下載qqwry.dat,新增到工程,具體的使用方法請參考網頁Python讀取純真IP資料庫:
# 注意新增引用 analy_user為我的工程名
from analy_user.IPLocator import *
# IPLocator呼叫一次即可,建議放在迴圈外,節約時間
IPL = IPLocator("qqwry.dat")
address = IPL.getIpAddr(IPL.str2ip(ip])).split(' ')
city = address[0]
如果想用純真資料庫,又想獲取經緯度,可以呼叫python的geopy庫,由城市名獲取經緯度。
from geopy.geocoders import Nominatim
from geopy.exc import GeocoderTimedOut
geolocator = Nominatim()
point= geolocator.geocode(city)
偶爾會提示server time out,原因不明。設定超時時間,可減少中斷次數,但治標不治本。
point = geolocator.geocode(city,timeout = 5000)
2、百度API-IP定位:
import urllib
import urllib2
def get_address(ip):
url = "http://api.map.baidu.com/location/ip?ip=%s&ak=你的AK祕鑰&coor=bd09ll" % ip
req = urllib2.Request(url)
res_data = urllib2.urlopen(req)
res = res_data.read().decode("unicode-escape") # 轉格式
jsonaddress = json.loads(res)
if not jsonaddress["status"]:
city = jsonaddress["content"]["address_detail"]["city"]
province = jsonaddress["content"]["address_detail"]["province"]
point = jsonaddress["content"]["point"]
return city ,province ,point
由於是像百度傳送請求,資料返回速度慢,建議將返回資料寫入檔案,建立ip_city_point 對照表。僅第一次建表時耗費時間。後期使用時先讀檔案,將ip_city_point 對照表快取起來;當傳入新的ip時,先讀快取,若已存在直接賦值,不存在則再發送請求並寫入檔案,這樣後面速度就很快了。