簡體   English   中英

如何使用Python對一堆IP地址進行地理定位?

[英]How can I geolocate a bunch of IP addresses with Python?

我有一個約300個IP地址的列表,我想在世界地圖上繪制。 你能粗略解釋一下如何用Python做到這一點嗎?

編輯:我也對問題的可視化部分感興趣

您可以使用hostip.info API 例如:

http://api.hostip.info/get_html.php?ip=64.233.160.0

因此,使用urllib2的Python代碼將是:

import urllib2
f = urllib2.urlopen("http://api.hostip.info/get_html.php?ip=64.233.160.0")
data = f.read()
f.close()

然后從返回的結果中檢索數據。

如果您需要經度和緯度,請使用position=true標志:

http://api.hostip.info/get_html.php?ip=64.233.160.0&position=true

您可以使用GeoIP ,它具有免費版和付費版。 還有一個方便的Python API

這是我在Python 3.x中的解決方案,在給定包含IP地址的數據幀的情況下返回地理位置信息; 在矢量化pd.series / dataframe上有效並行化應用函數是可行的方法。

為了在地圖上繪制記錄,對緯度和經度信息進行子集化,然后使用合適的Mapping API(如Google Maps Api或tableau)來幫助實現數據可視化。

將兩個流行的庫的性能對比返回位置

TLDR:使用geolite2方法。

1. geolite2從包geolite2

輸入

# !pip install maxminddb-geolite2
import time
from geolite2 import geolite2
geo = geolite2.reader()
df_1 = train_data.loc[:50,['IP_Address']]

def IP_info_1(ip):
    try:
        try:
        x = geo.get(ip)
    except ValueError:   #Faulty IP value
        return np.nan
    try:
        return x['country']['names']['en'] if x is not None else np.nan
    except KeyError:   #Faulty Key value
        return np.nan

s_time = time.time()
# map IP --> country
#apply(fn) applies fn. on all pd.series elements
df_1['country'] = df_1.loc[:,'IP_Address'].apply(IP_info_1)
print(df_1.head(), '\n')
print('Time:',str(time.time()-s_time)+'s \n')

print(type(geo.get('48.151.136.76')))

產量

       IP_Address         country
0   48.151.136.76   United States
1    94.9.145.169  United Kingdom
2   58.94.157.121           Japan
3  193.187.41.186         Austria
4   125.96.20.172           China 

Time: 0.09906983375549316s 

<class 'dict'>

2.來自ip2geotools庫的DbIpCity

輸入

# !pip install ip2geotools
import time
s_time = time.time()
from ip2geotools.databases.noncommercial import DbIpCity
df_2 = train_data.loc[:50,['IP_Address']]
def IP_info_2(ip):
    try:
        return DbIpCity.get(ip, api_key = 'free').country
    except:
        return np.nan
df_2['country'] = df_2.loc[:, 'IP_Address'].apply(IP_info_2)
print(df_2.head())
print('Time:',str(time.time()-s_time)+'s')

print(type(DbIpCity.get('48.151.136.76',api_key = 'free')))

產量

       IP_Address country
0   48.151.136.76      US
1    94.9.145.169      GB
2   58.94.157.121      JP
3  193.187.41.186      AT
4   125.96.20.172      CN

Time: 80.53318452835083s 

<class 'ip2geotools.models.IpLocation'>

之所以巨大的時間差異可能是由於輸出的數據結構, 直接從字典進行子集化,這似乎比從specialized ip2geotools.models.IpLocation對象索引更有效。

此外,第一種方法的輸出是包含地理位置數據的字典,子集專門用於獲取所需信息:

x = geolite2.reader().get('48.151.136.76')
print(x)

>>>
    {'city': {'geoname_id': 5101798, 'names': {'de': 'Newark', 'en': 'Newark', 'es': 'Newark', 'fr': 'Newark', 'ja': 'ニューアーク', 'pt-BR': 'Newark', 'ru': 'Ньюарк'}},

 'continent': {'code': 'NA', 'geoname_id': 6255149, 'names': {'de': 'Nordamerika', 'en': 'North America', 'es': 'Norteamérica', 'fr': 'Amérique du Nord', 'ja': '北アメリカ', 'pt-BR': 'América do Norte', 'ru': 'Северная Америка', 'zh-CN': '北美洲'}}, 

'country': {'geoname_id': 6252001, 'iso_code': 'US', 'names': {'de': 'USA', 'en': 'United States', 'es': 'Estados Unidos', 'fr': 'États-Unis', 'ja': 'アメリカ合衆國', 'pt-BR': 'Estados Unidos', 'ru': 'США', 'zh-CN': '美國'}}, 

'location': {'accuracy_radius': 1000, 'latitude': 40.7355, 'longitude': -74.1741, 'metro_code': 501, 'time_zone': 'America/New_York'}, 

'postal': {'code': '07102'}, 

'registered_country': {'geoname_id': 6252001, 'iso_code': 'US', 'names': {'de': 'USA', 'en': 'United States', 'es': 'Estados Unidos', 'fr': 'États-Unis', 'ja': 'アメリカ合衆國', 'pt-BR': 'Estados Unidos', 'ru': 'США', 'zh-CN': '美國'}}, 

'subdivisions': [{'geoname_id': 5101760, 'iso_code': 'NJ', 'names': {'en': 'New Jersey', 'es': 'Nueva Jersey', 'fr': 'New Jersey', 'ja': 'ニュージャージー州', 'pt-BR': 'Nova Jérsia', 'ru': 'Нью-Джерси', 'zh-CN': '新澤西州'}}]}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM