根据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定位:

首先需要申请一个申请密钥(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时,先读缓存,若已存在直接赋值,不存在则再发送请求并写入文件,这样后面速度就很快了。

你可能感兴趣的:(python)