57

有没有办法通过查看IP地址来找出国家名称?我的意思是,国家有特定的 IP 地址范围吗?例如,澳大利亚的 IP 地址只能在以下范围内123.45.56.89 - 231.54.65.98(仅作为示例)

4

13 回答 13

34

不,你不能 - IP 地址会不时重新分配和重新分配,因此 IP 到位置的映射也会随着时间而改变。

如果您想找出 IP 地址当前映射到的位置,可以从 MaxMind 下载地理定位数据库,例如 GeoLite,或者使用http://ipinfo.io(我自己的服务)之类的 API,它也会提供您的其他详细信息:

$ curl ipinfo.io/8.8.8.8
{
  "ip": "8.8.8.8",
  "hostname": "google-public-dns-a.google.com",
  "loc": "37.385999999999996,-122.0838",
  "org": "AS15169 Google Inc.",
  "city": "Mountain View",
  "region": "California",
  "country": "US",
  "phone": 650
}
于 2014-08-07T06:39:45.847 回答
22

我认为您正在寻找的是 IP 地理定位数据库或服务提供商。那里有很多,有些是免费的(得到你所支付的)。

虽然我之前没有使用过这项服务,但它声称是实时的。 https://kickfire.com/kf-api

这是来自 Abstract API 的另一个 IP 地理位置 API - https://www.abstractapi.com/ip-geolocation-api

但只需在 IP geo 上进行谷歌搜索,您将获得比您需要的更多的结果。

于 2012-03-21T10:10:44.337 回答
4

您可以使用ipdata.co来执行查找

此答案使用非常有限的“测试”API 密钥,仅用于测试几个调用。注册您自己的免费 API 密钥并每天收到多达 1500 个开发请求。

curl https://api.ipdata.co/23.221.76.66?api-key=test

Ipdata 在全球有 10 个端点,每个端点每秒能够处理超过 10,000 个请求!

{
    "ip": "23.221.76.66",
    "city": "Cambridge",
    "region": "Massachusetts",
    "region_code": "MA",
    "country_name": "United States",
    "country_code": "US",
    "continent_name": "North America",
    "continent_code": "NA",
    "latitude": 42.3626,
    "longitude": -71.0843,
    "asn": "AS20940",
    "organisation": "Akamai International B.V.",
    "postal": "02142",
    "calling_code": "1",
    "flag": "https://ipdata.co/flags/us.png",
    "emoji_flag": "\ud83c\uddfa\ud83c\uddf8",
    "emoji_unicode": "U+1F1FA U+1F1F8",
    "is_eu": false,
    "languages": [
        {
            "name": "English",
            "native": "English"
        }
    ],
    "currency": {
        "name": "US Dollar",
        "code": "USD",
        "symbol": "$",
        "native": "$",
        "plural": "US dollars"
    },
    "time_zone": {
        "name": "America/New_York",
        "abbr": "EDT",
        "offset": "-0400",
        "is_dst": true,
        "current_time": "2018-04-19T06:32:30.690963-04:00"
    },
    "threat": {
        "is_tor": false,
        "is_proxy": false,
        "is_anonymous": false,
        "is_known_attacker": false,
        "is_known_abuser": false,
        "is_threat": false,
        "is_bogon": false
    }
}⏎ 
于 2017-11-06T17:34:57.157 回答
4

IP 地址非常常用于地理定位,即按访问者的位置/国家/地区定制网站内容,但它们与国家/地区没有永久关联,并且经常被重新分配。

为了完成你想要的,你需要保持最新的查找,以使用数据库或地理定位 API 将 IP 地址映射到国家/地区。这是一个例子:

> https://ipapi.co/8.8.8.8/country
US

> https://ipapi.co/8.8.8.8/country_name
United States

或者您可以使用完整的 API 来获取IP 地址的完整位置,例如

https://ipapi.co/8.8.8.8/json

{
    "ip": "8.8.8.8",
    "city": "Mountain View",
    "region": "California",
    "region_code": "CA",
    "country": "US",
    "country_name": "United States",
    "continent_code": "NA",
    "postal": "94035",
    "latitude": 37.386,
    "longitude": -122.0838,
    "timezone": "America/Los_Angeles",
    "utc_offset": "-0800",
    "country_calling_code": "+1",
    "currency": "USD",
    "languages": "en-US,es-US,haw,fr",
    "asn": "AS15169",
    "org": "Google Inc."
}
于 2018-02-09T15:50:13.817 回答
4

我知道这是一个非常古老的帖子,但是为了那些登陆这里并寻找解决方案的用户,如果您使用 Cloudflare 作为您的 DNS,那么您可以激活 IP 地理定位并从请求标头中获取值,

这是通过网络选项卡在 Cloudflare 中启用 IP 地理定位后 C# 中的代码片段

 var countryCode = HttpContext.Request.Headers.Get("cf-ipcountry"); // in older asp.net versions like webform use HttpContext.Current.Request. ...
 var countryName = new RegionInfo(CountryCode)?.EnglishName;

您可以简单地将其映射到其他编程语言,请在此处查看 Cloudflare 的文档


但是,如果您真的坚持使用 3rd 方解决方案来获得有关使用其 IP 的访问者的更准确信息,这里是一个完整的、可立即使用的 C# 实现:

我使用的第 3 方是https://ipstack.com,您可以简单地注册一个免费计划并获得一个访问令牌以用于每月 10K API 请求,我使用 JSON 模型来检索并喜欢转换所有API给我的信息,我们开始吧:

DTO:

    using System;
    using Newtonsoft.Json;

     public partial class GeoLocationModel
     {
        [JsonProperty("ip")]
        public string Ip { get; set; }

        [JsonProperty("hostname")]
        public string Hostname { get; set; }

        [JsonProperty("type")]
        public string Type { get; set; }

        [JsonProperty("continent_code")]
        public string ContinentCode { get; set; }

        [JsonProperty("continent_name")]
        public string ContinentName { get; set; }

        [JsonProperty("country_code")]
        public string CountryCode { get; set; }

        [JsonProperty("country_name")]
        public string CountryName { get; set; }

        [JsonProperty("region_code")]
        public string RegionCode { get; set; }

        [JsonProperty("region_name")]
        public string RegionName { get; set; }

        [JsonProperty("city")]
        public string City { get; set; }

        [JsonProperty("zip")]
        public long Zip { get; set; }

        [JsonProperty("latitude")]
        public double Latitude { get; set; }

        [JsonProperty("longitude")]
        public double Longitude { get; set; }

        [JsonProperty("location")]
        public Location Location { get; set; }

        [JsonProperty("time_zone")]
        public TimeZone TimeZone { get; set; }

        [JsonProperty("currency")]
        public Currency Currency { get; set; }

        [JsonProperty("connection")]
        public Connection Connection { get; set; }

        [JsonProperty("security")]
        public Security Security { get; set; }
     }

    public partial class Connection
    {
        [JsonProperty("asn")]
        public long Asn { get; set; }

        [JsonProperty("isp")]
        public string Isp { get; set; }
    }

    public partial class Currency
    {
        [JsonProperty("code")]
        public string Code { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("plural")]
        public string Plural { get; set; }

        [JsonProperty("symbol")]
        public string Symbol { get; set; }

        [JsonProperty("symbol_native")]
        public string SymbolNative { get; set; }
    }

    public partial class Location
    {
        [JsonProperty("geoname_id")]
        public long GeonameId { get; set; }

        [JsonProperty("capital")]
        public string Capital { get; set; }

        [JsonProperty("languages")]
        public Language[] Languages { get; set; }

        [JsonProperty("country_flag")]
        public Uri CountryFlag { get; set; }

        [JsonProperty("country_flag_emoji")]
        public string CountryFlagEmoji { get; set; }

        [JsonProperty("country_flag_emoji_unicode")]
        public string CountryFlagEmojiUnicode { get; set; }

        [JsonProperty("calling_code")]
        public long CallingCode { get; set; }

        [JsonProperty("is_eu")]
        public bool IsEu { get; set; }
    }

    public partial class Language
    {
        [JsonProperty("code")]
        public string Code { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("native")]
        public string Native { get; set; }
    }

    public partial class Security
    {
        [JsonProperty("is_proxy")]
        public bool IsProxy { get; set; }

        [JsonProperty("proxy_type")]
        public object ProxyType { get; set; }

        [JsonProperty("is_crawler")]
        public bool IsCrawler { get; set; }

        [JsonProperty("crawler_name")]
        public object CrawlerName { get; set; }

        [JsonProperty("crawler_type")]
        public object CrawlerType { get; set; }

        [JsonProperty("is_tor")]
        public bool IsTor { get; set; }

        [JsonProperty("threat_level")]
        public string ThreatLevel { get; set; }

        [JsonProperty("threat_types")]
        public object ThreatTypes { get; set; }
    }

    public partial class TimeZone
    {
        [JsonProperty("id")]
        public string Id { get; set; }

        [JsonProperty("current_time")]
        public DateTimeOffset CurrentTime { get; set; }

        [JsonProperty("gmt_offset")]
        public long GmtOffset { get; set; }

        [JsonProperty("code")]
        public string Code { get; set; }

        [JsonProperty("is_daylight_saving")]
        public bool IsDaylightSaving { get; set; }
    }

帮手:

    using System.Configuration;
    using System.IO;
    using System.Net;
    using System.Threading.Tasks;

    public class GeoLocationHelper
    {
        public static async Task<GeoLocationModel> GetGeoLocationByIp(string ipAddress)
        {
            var request = WebRequest.Create(string.Format("http://api.ipstack.com/{0}?access_key={1}", ipAddress, ConfigurationManager.AppSettings["ipStackAccessKey"]));
            var response = await request.GetResponseAsync();
            using (var stream = new StreamReader(response.GetResponseStream()))
            {
                var jsonGeoData = await stream.ReadToEndAsync();
                return Newtonsoft.Json.JsonConvert.DeserializeObject<GeoLocationModel>(jsonGeoData);
            }
        }
    }
于 2020-06-03T10:42:04.783 回答
3

那并没那么简单。IP 地址不是分配给国家本身,而是分配给公司和组织。

但也许这可以帮助你: http: //www.maxmind.com/app/geolitecountry

于 2012-03-21T09:50:37.530 回答
2

您可以尝试使用https://ip-api.io - 在其他 IP 信息中返回国家/地区的地理位置 api。

例如使用 Node.js

const request = require('request-promise')

request('http://ip-api.io/api/json/1.2.3.4')
  .then(response => console.log(JSON.parse(response)))
  .catch(err => console.log(err))
于 2017-08-06T20:41:17.100 回答
2

Amazon 的 CloudFront 内容交付网络现在可以配置为将此信息作为标头传递。鉴于亚马逊的规模(它们又大又稳定,不会去任何地方),而且这是代码配置(无需学习第三方 API 或维护代码),周围的人都认为这是最好的选择。

如果您不使用 AWS CloudFront,我会查看您的 CDN 是否具有可以打开的类似标头选项。通常,大型提供商会迅速推动功能对等。如果您不使用 CDN,您可以将 CloudFront 放在您的基础设施前面,并简单地将源设置为解析为您当前使用的任何内容。

此外,在 CDN 级别解决此问题也很有意义。您的 CDN 已经必须确定地理位置以将用户路由到最近的内容节点,不妨将这些信息传递出去,而不是通过第三方 API 计算两次(这成为您的应用程序的瓶颈,等待地理位置位置查找来解决)。不需要做两次这项工作(第二次,可以说弹性较差[例如,第 3 方地理查找])。

https://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/

地理定位CloudFront-Viewer-Country– CloudFront 将检测用户的原籍国并在 标题中将县代码传递给您。您可以使用此信息来自定义您的回复,而无需使用特定于每个国家/地区的 URL。

于 2017-12-20T21:40:56.457 回答
2

是的,正如您提到的,国家/地区有特定的 IP 地址范围。

例如,澳大利亚在 16777216 - 16777471 之间。中国在 16777472 - 16778239 之间。但一个国家可能有多个范围。例如,澳大利亚在 16778240 - 16779263 之间也有这个范围

(这些是 IP 地址的数字转换。这取决于您使用的是 IPv4 还是 IPv6)

有关这些范围的更多信息,请参见此处:http: //software77.net/cidr-101.html

我们获取网站访问者的 IP 地址,有时希望针对特定国家/地区进行相关活动。我们使用批量转换工具,但后来决定在 Excel 文件中定义规则并在工具中进行转换。我们已经构建了这个 Excel 模板:https ://www.someka.net/excel-template/ip-to-country-converter/

现在我们将其用于我们自己的需要并出售它。我不希望它成为推销,但对于那些正在寻找简单解决方案的人来说,可以从中受益。

于 2018-11-22T12:53:44.287 回答
1

可能这两个链接可以帮助您将IP 地址与国家/地区相关联

http://en.wikipedia.org/wiki/Regional_Internet_Registry

于 2012-03-21T10:02:30.300 回答
1

我同意上述答案,从 IP 地址获取国家/地区的最佳方法是 Maxmind。

如果你想用java编写代码,你可能想使用geoip-api-1.2.10.jar和geoIP dat文件(GeoIPCity.dat),可以通过google找到。

以下代码可能有助于您获取与位置相关的几乎所有信息,我也在使用相同的代码。

public static String getGeoDetailsUsingMaxmind(String ipAddress, String desiredValue) 
    {
        Location getLocation;
        String returnString = "";
        try
        {
            String geoIPCity_datFile = System.getenv("AUTOMATION_HOME").concat("/tpt/GeoIP/GeoIPCity.dat");
            LookupService isp = new LookupService(geoIPCity_datFile);
            getLocation = isp.getLocation(ipAddress);
            isp.close();

            //Getting all location details 
            if(desiredValue.equalsIgnoreCase("latitude") || desiredValue.equalsIgnoreCase("lat"))
            {
                returnString = String.valueOf(getLocation.latitude);
            }
            else if(desiredValue.equalsIgnoreCase("longitude") || desiredValue.equalsIgnoreCase("lon"))
            {
                returnString = String.valueOf(getLocation.longitude);
            }
            else if(desiredValue.equalsIgnoreCase("countrycode") || desiredValue.equalsIgnoreCase("country"))
            {
                returnString = getLocation.countryCode;
            }
            else if(desiredValue.equalsIgnoreCase("countryname"))
            {
                returnString = getLocation.countryName;
            }
            else if(desiredValue.equalsIgnoreCase("region"))
            {
                returnString = getLocation.region;
            }
            else if(desiredValue.equalsIgnoreCase("metro"))
            {
                returnString = String.valueOf(getLocation.metro_code);
            }
            else if(desiredValue.equalsIgnoreCase("city"))
            {
                returnString = getLocation.city;
            }
            else if(desiredValue.equalsIgnoreCase("zip") || desiredValue.equalsIgnoreCase("postalcode"))
            {
                returnString = getLocation.postalCode;
            }
            else
            {
                returnString = "";
                System.out.println("There is no value found for parameter: "+desiredValue);
            }

            System.out.println("Value of: "+desiredValue + " is: "+returnString + " for ip address: "+ipAddress);
        }
        catch (Exception e) 
        {
            System.out.println("Exception occured while getting details from max mind. " + e);
        }
        finally
        {
            return returnString;
        }
    }
于 2014-11-07T09:15:08.073 回答
1

是的,您可以从https://lite.ip2location.com/ip-address-ranges-by-country按国家/地区下载 IP 地址范围

可以看到每个国家都有多个范围,而且变化频繁。

于 2018-02-28T02:12:12.177 回答
1

这是我在 Python 3.x 中的解决方案,在给定包含IP 地址的数据帧的情况下返回地理位置信息;在矢量化 pd.series/dataframe 上有效地并行应用函数是要走的路。

将对比两个流行库的性能返回位置

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:
        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. 从库DbIpCity中打包ip2geotools

输入

# !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'>

巨大的时间差异的一个原因可能是由于输出的数据结构,即从字典直接子集似乎比从专门的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': '新泽西州'}}]}
于 2019-07-12T12:13:33.120 回答