如何通过IP地址进行精准定位

在甲方工作的朋友可能会遇到这样的问题,服务器或者系统经常被扫描,通过IP地址我们只能查到某一个市级城市,如下图:


IP定位,地图定位,API,地理位置


当我们想具体到街道甚至门牌号,该怎么办?


偶然间发现百度地图有高精度IP定位API的接口,通过该接口我们可以通过IP地址定位到具体的地理位置,甚至能精确到门牌号及周围的标志性建筑。该接口的说明地址为:http://lbsyun.baidu.com/index.php?title=webapi/high-acc-ip


若想要使用该接口进行查询,必须先申请一个密钥(AK),如下图:


IP定位,地图定位,API,地理位置


申请过程就不进行说明了。API的接口参数说明和返回参数说明也不过多的介绍,大家可以看一看。因为我想返回基础定位结果+地址信息+POI信息,所以我将请求参数extensions的值设置为3。一次完整的http请求为:http://api.map.baidu.com/highacciploc/v1?qcip=183.55.116.90&qterm=pc&ak=“你的 密钥(AK)”&coord=bd09ll&extensions=3 。请求结果如下图:


IP定位,地图定位,API,地理位置


结果为json格式数据:

1
{ "content" :{ "location" :{ "lat" :23.06588, "lng" :115.404586}, "locid" : "925a2a9e3ac5be1cf003afd23c344ab3" , "radius" :30, "confidence" :0.5, "address_component" :{ "country" : "中国" , "province" : "广东省" , "city" : "汕尾市" , "district" : "海丰县" , "street" : "新平路" , "street_number" : "" , "admin_area_code" :441521}, "formatted_address" : "广东省汕尾市海丰县新平路" , "business" : "公平" }, "result" :{ "error" :161, "loc_time" : "2016-10-19 21:53:28" }}

 

我们需要的字段为:content字段里面的formatted_address。当然我们也可以将location里面的经度和纬度提取出来从而显示在地图上面。有的IP地址会返回pois数据,比如:183.55.116.95。返回参数如下:

1
{ "content" :{ "location" :{ "lat" :23.082367, "lng" :115.466276}, "locid" : "3fb96555906fff3100ff21119142ccd5" , "radius" :30, "confidence" :1.0,

 

1
"address_component" :{ "country" : "中国" , "province" : "广东省" , "city" : "汕尾市" , "district" : "海丰县" , "street" : "S335" , "street_number" : "" , "admin_area_code" :441521},

 

1
"formatted_address" : "广东省汕尾市海丰县S335" , "pois" :[{ "name" : "双墩村" , "address" : "汕尾市海丰县三三五省道" , "tag" : "行政地标;村庄" , "location" :{ "lat" :23.082422, "lng" :115.465348},

 

1
"uid" : "18010998377147269119" },{ "name" : "双墩村委会" , "address" : "汕尾市海丰县" , "tag" : "政府机构;各级政府" , "location" :{ "lat" :23.083394, "lng" :115.465914}, "uid" : "17661602237861855231" },

1
{ "name" : "长联塘尾" , "address" : "汕尾市海丰县" , "tag" : "行政地标;村庄" , "location" :{ "lat" :23.081358, "lng" :115.467315}, "uid" : "18010998372852301823" },

1
{ "name" : "双墩小学" , "address" : "335省道附近" , "tag" : "教育培训;小学" , "location" :{ "lat" :23.083336, "lng" :115.465061}, "uid" : "17661601958688980991" },

1
{ "name" : "大溪头" , "address" : "汕尾市海丰县" , "tag" : "行政地标;村庄" , "location" :{ "lat" :23.090326, "lng" :115.465995}, "uid" : "18010998368557334527" }],

 

1
"location_description" : "双墩村东104米" }, "result" :{ "error" :161, "loc_time" : "2016-10-19 22:03:31" }}

 

此时我们可以把pois字段也提取出来,值得注意的是pois为数组,我们可以遍历数组数据。


通过上面的分析,用python简单的写了一个脚本,具体代码如下:

1
# -*- coding:utf-8 -*- # author:allen权 import sys import urllib2 import json def get_ip_information(ip):

 

1
url= 'http://api.map.baidu.com/highacciploc/v1?qcip=' +ip+ '&qterm=pc&ak=' 你的密钥(AK) '&coord=bd09ll&extensions=3'  poiss= ''  request = urllib2.Request(url)

 

1
page = urllib2.urlopen(request, timeout=10)  data_json = page.read()  data_dic = json.loads(data_json)  if (data_dic.has_key( "content" )):  content=data_dic[ "content" ]

1
address_component=content[ "address_component" ]  formatted_address=content[ "formatted_address" ]  print "该IP地址的具体位置为:"  print address_component[ "country" ]

1
print formatted_address  if (content.has_key( "pois" )):  print "该IP地址附近POI信息如下:"  pois = content[ "pois" for index in range(len(pois)):

1
pois_name = pois[index][ "name" ]  pois_address = pois[index][ "address" ]  print pois_name, pois_address  else :  print 'IP地址定位失败!!!' if __name__ == '__main__' :

 

1
get_ip_information( '183.55.116.95' )


大家把脚本上面的参数ak值改为自己的密钥即可。测试截图如下:


IP定位,地图定位,API,地理位置


再放一张自己IP的测试截图:


IP定位,地图定位,API,地理位置


确实精确到了路名,很准确,虽然没有pois的信息。


最后声明一下,成功率:综合定位成功率 65%  ,精度:90% 误差 80m 以内;95% 误差 350m。这是官方给出的数据,所说有一定的概率是查询失败的!!!

 

原文链接:http://www.phpxs.com/post/5433/

你可能感兴趣的:(http)