最近想统计下公司用户在中国地图上的分别情况,但用户注册表中填写的单位信息比较混乱,提取省份、城市名称较困难,最后决定用ip地址来查找对应信息。搜索到两种常用的方式:
首先需要下载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)
首先需要申请一个申请密钥(AK)(http://lbsyun.baidu.com/index.php?title=webapi/ip-api),不知道白名单可使用默认地址0.0.0.0/0申请,按照官网上操作步骤,请求中传入IP 和 AK秘钥:
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时,先读缓存,若已存在直接赋值,不存在则再发送请求并写入文件,这样后面速度就很快了。