1. 程式人生 > >根據IP定位城市名稱/經緯度

根據IP定位城市名稱/經緯度

最近想統計下公司使用者在中國地圖上的分別情況,但使用者登錄檔中填寫的單位資訊比較混亂,提取省份、城市名稱較困難,最後決定用ip地址來查詢對應資訊。搜尋到兩種常用的方式:

  1. 採用純真資料庫qqwry.dat,傳入ip返回省+城市名稱,無經緯度資訊;缺點:返回的地址資訊太詳細,有的能定位到小區名稱,不利於歸類統計數量;優點:qqwry.dat資料庫更新快且地址資訊更具體,部分能定位到縣或小區。
  2. 利用百度的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時,先讀快取,若已存在直接賦值,不存在則再發送請求並寫入檔案,這樣後面速度就很快了。