通過ip地址精準定位
在甲方工作的朋友可能會遇到這樣的問題,伺服器或者系統經常被掃描,通過IP地址我們只能查到某一個市級城市,如下圖:
當我們想具體到街道甚至門牌號,該怎麼辦?
偶然間發現百度地圖有高精度IP定位API的介面,通過該介面我們可以通過IP地址定位到具體的地理位置,甚至能精確到門牌號及周圍的標誌性建築。該介面的說明地址為:http://lbsyun.baidu.com/index.php?title=webapi/high-acc-ip
若想要使用該介面進行查詢,必須先申請一個金鑰(AK),如下圖:
申請過程就不進行說明了。API的介面引數說明和返回引數說明也不過多的介紹,大家可以看一看。因為我想返回基礎定位結果+地址資訊+POI資訊,所以我將請求引數extensions的值設定為3。一次完整的http請求為:
結果為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。這是官方給出的資料,所說有一定的概率是查詢失敗的!!!