数据挖掘:使用python+requests结合高德+百度+腾讯地图API处理IP数据,获得IP地理位置信息

    技术2022-07-12  78

    简介

    利用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地址

    Processed: 0.008, SQL: 9