简介
利用IP得到地理位置信息
在现在这样的信息化社会,人们在访问互联网时总会留下痕迹。其中最多的就是IP数据
怎么样来利用IP数据来分析用户数据呢?其中最好挖掘的肯定非地理位置信息莫属了
地理位置信息有很多用途,就比如现在新冠疫情在全球大肆传播,粗略追踪用户是否到过某些疫情高发地区等
一般情况下,IP地址定位可以精确到市,这也很不错了
IP定位API
本次笔者应用了三家地图的开放平台API来同时处理数据
目前比较权威的IP数据库还有阿里云、淘宝IP地址库等
以淘宝IP地址库为例,其最高支持并发数仅为1qps,非常的慢,而且目前不知道为什么不能用了
而地图开发者API无论从并发数和日调用上限都能满足我们的需求
有的还可以精确到区县级
高德地图个人认证开发者日调用可达30万次,并发数200次每秒
高德相关文档可见https://lbs.amap.com/fn/ip_locate_v4(其他平台自己搜)
他的精度可以到区县,但是遇见某些IP很有可能挂掉
但是如果高德+百度+腾讯三家一起用
已经能满足我们基本需求
而且可以保证IP被最好的分类
笔者试过一个2万条的数据,三家合用的分类率很高,只有万分之四三家都识别不出,可见三者合用的好处
使用
注册并获得key
去各家官网获得key,并查看文档
比如高德地图:https://lbs.amap.com/api/webservice/summary
初步使用
获得key之后,我们可以开始我们的一个小应用
在百度中搜索IP,获得自己的IP
然后试着解析自己的IP
以高德地图为例
import json
import requests as rq
url="https://restapi.amap.com/v4/ip?key=你的key"
data={
"ip":"你的IP"
}
ip = rq.get(url,params=data)
这样,你就可以得到自己的地址数据了
高德地图还给出了大致的经纬度,并且还比较准,能够精确到区县
三者结合使用
三家API中,高德给出的配额最多,但是有一些IP它无法解析,这个时候就要百度地图和腾讯地图上阵了
一个可能的转换程序如下
def ipapi(ip):
url1="https://restapi.amap.com/v4/ip?key=你的key"
data={}
back={}
data["ip"]=ip
api1=rq.get(url1,params=data)
api1=json.loads(api1.text)
if api1['errcode']==0:
back['province']=api1['data']['pcd']['province']
back['city']=api1['data']['pcd']['city']
back['county']=api1['data']['pcd']['county']
back['lng']=api1['data']['lng']
back['lat']=api1['data']['lat']
back['code']='Gaode'
return back
url2="http://api.map.baidu.com/location/ip?ak=你的key&coor=你的编码方式"
data={}
back={}
data["ip"]=ip
api2=rq.get(url2,params=data)
api2=json.loads(api2.text)
if api2['status']==0:
back['province']=api2['content']['address_detail']['province']
back['city']=api2['content']['address_detail']['city']
back['county']='NULL'
back['lng']=api2['content']['point']['x']
back['lat']=api2['content']['point']['y']
back['code']='Baidu'
return back
url3="https://apis.map.qq.com/ws/location/v1/ip?key=你的key"
data={}
back={}
data["ip"]=ip
api3=rq.get(url3,params=data)
api3=json.loads(api3.text)
if api3['status']==0:
back['province']=api3['result']['ad_info']['province']
back['city']=api3['result']['ad_info']['city']
back['county']='NULL'
back['lng']=api3['result']['location']['lng']
back['lat']=api3['result']['location']['lat']
back['code']='Tencent'
return back
qsz={'province': 'NULL',
'city': 'NULL',
'county': 'NULL',
'lng': 'NULL',
'lat': 'NULL',
'code': 'NULL'}
return qsz
正常解析的情况下,会返回一个包含所需信息的字典
province是省
city是市
county是县区(只有高德地图有)
lng经度
lat维度
code解析服务商
有些IP强到3家都无法解析,这时返回一个空字典而不是None显然是保持连续性的更好选择
应用于我们的数据
假设含有信息的DataFrame共有cols行,其中IP地址在第二列
你可以这样使用
ips=[]
for i in range(cols):
ips.append(ipapi(data.iloc[i,1])
print(i)#把i输出,好知道进度
你会得到一个字典列表,我们用pandas将其转换为DataFrame
data2=pd.DataFrame(ips)
print(data2.head())
可以看到这时的data2包含了经纬度和定位信息,我们将其与原DataFrame连接
data3= pd.concat([data,data2],axis=1)
这时我们就成功的解析了IP地址