在甲方工作的朋友可能会遇到这样的问题,服务器或者系统经常被扫描,通过IP地址我们只能查到某一个市级城市,如下图:
当我们想具体到街道甚至门牌号,该怎么办?
偶然间发现百度地图有高精度IP定位API的接口,通过该接口我们可以通过IP地址定位到具体的地理位置,甚至能精确到门牌号及周围的标志性建筑。该接口的说明地址为:http://lbsyun.baidu.com/index.php?title=webapi/high-acc-ip
若想要使用该接口进行查询,必须先申请一个密钥(AK),如下图:
申请过程就不进行说明了。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 。请求结果如下图:
结果为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的测试截图:
确实精确到了路名,很准确,虽然没有pois的信息。
最后声明一下,成功率:综合定位成功率 65% ,精度:90% 误差 80m 以内;95% 误差 350m。这是官方给出的数据,所说有一定的概率是查询失败的!!!
原文链接:http://www.phpxs.com/post/5433/