一、背景
在开发过程中,我们经常需要根据用户 IP 获取其归属地信息,用于地域化运营、风控、日志分析等场景。
网上免费的 IP 查询接口不少,但很多要么停服、要么要收费、要么定位不准。本文介绍一个真正免费、无需注册、国内精度高的公开 API,并提供 C# 开箱即用的代码。
二、数据源:ip9.com.cn
ip9.com.cn 是一个国内开发者维护的免费 IP 归属地查询 API,专为国内环境优化。
2.1 核心特点
- 无需注册:
- 国内精度高: 支持到区县级,比
ip-api.com 等国际服务精准得多 - 信息丰富: 返回国家、省份、城市、区县、运营商、经纬度、邮编、区号
- 调用简单:
- 频率限制:
2.2 接口地址
| |
|---|
| GET https://ip9.com.cn/get |
| GET https://ip9.com.cn/get?ip={IP地址} |
示例:
GET https://ip9.com.cn/get?ip=123.45.67.89
(示例 IP 为占位符,请替换为实际 IP)
2.3 返回数据格式
{ "ret": 200, "data": { "ip": "123.45.67.89", "country": "韩国", "country_code": "kr", "prov": "首尔", "city": "首尔", "city_code": "seoul", "city_short_code": "s", "area": "", "post_code": "", "area_code": "", "isp": "SamsungSDS", "lng": "126.97", "lat": "37.51", "long_ip": 2066563929, "big_area": "" }, "qt": 0.001}
2.4 关键字段说明
| |
|---|
prov | |
city | |
area | |
isp | |
lng | |
post_code | |
area_code | |
三、C# 完整实现
3.1 数据模型定义
using System.Text.Json.Serialization;
public class Ip9Response
{
[JsonPropertyName("ret")]
public int Ret { get; set; }
[JsonPropertyName("data")]
public Ip9Data Data { get; set; }
[JsonPropertyName("qt")]
public double QueryTime { get; set; }
}
public class Ip9Data
{
[JsonPropertyName("ip")]
public string Ip { get; set; }
[JsonPropertyName("country")]
public string Country { get; set; }
[JsonPropertyName("country_code")]
public string CountryCode { get; set; }
[JsonPropertyName("prov")]
public string Province { get; set; }
[JsonPropertyName("city")]
public string City { get; set; }
[JsonPropertyName("area")]
public string Area { get; set; }
[JsonPropertyName("isp")]
public string Isp { get; set; }
[JsonPropertyName("lng")]
public string Longitude { get; set; }
[JsonPropertyName("lat")]
public string Latitude { get; set; }
[JsonPropertyName("post_code")]
public string PostCode { get; set; }
[JsonPropertyName("area_code")]
public string AreaCode { get; set; }
[JsonPropertyName("big_area")]
public string BigArea { get; set; }
}
3.2 查询客户端
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
public class Ip9Client
{
private static readonly HttpClient _httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(10)
};
/// <summary>
/// 查询指定 IP 的归属地信息
/// </summary>
public static async Task<Ip9Response> GetIpInfoAsync(string ip)
{
string url = $"https://ip9.com.cn/get?ip={ip}";
var response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
string json = await response.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
return JsonSerializer.Deserialize<Ip9Response>(json, options);
}
/// <summary>
/// 查询当前公网 IP 的归属地信息
/// </summary>
public static async Task<Ip9Response> GetCurrentIpInfoAsync()
{
string url = "https://ip9.com.cn/get";
var response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
string json = await response.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
return JsonSerializer.Deserialize<Ip9Response>(json, options);
}
}
3.3 调用示例
class Program
{
static async Task Main(string[] args)
{
// 示例 IP,请替换为实际 IP
string ip = "123.45.67.89";
var result = await Ip9Client.GetIpInfoAsync(ip);
if (result != null && result.Ret == 200)
{
var data = result.Data;
Console.WriteLine($"IP: {data.Ip}");
Console.WriteLine($"归属地: {data.Country} {data.Province} {data.City} {data.Area}");
Console.WriteLine($"运营商: {data.Isp}");
Console.WriteLine($"坐标: {data.Longitude}, {data.Latitude}");
Console.WriteLine($"邮编: {data.PostCode} 区号: {data.AreaCode}");
}
else
{
Console.WriteLine($"查询失败: ret={result?.Ret}");
}
}
}
3.4 运行结果
IP: 123.45.67.89
归属地: 中国 浙江省 杭州市 西湖区
运营商: 中国电信
坐标: 120.1552, 30.2729
邮编: 310000 区号: 0571
四、生产环境最佳实践
4.1 加缓存(避免重复查询)
同一个 IP 的归属地是静态数据,查询一次后应该缓存起来,避免重复调用接口。
public class IpQueryService
{
private static readonly Dictionary<string, Ip9Data> _cache = new Dictionary<string, Ip9Data>();
private static readonly object _lock = new object();
public static async Task<Ip9Data> GetIpInfoWithCacheAsync(string ip)
{
lock (_lock)
{
if (_cache.TryGetValue(ip, out Ip9Data cached))
return cached;
}
var result = await Ip9Client.GetIpInfoAsync(ip);
if (result?.Ret == 200)
{
lock (_lock)
{
if (!_cache.ContainsKey(ip))
_cache[ip] = result.Data;
}
return result.Data;
}
return null;
}
}
4.2 添加降级策略
接口偶尔可能不可用,建议配置备用数据源或默认返回值。
public static async Task<Ip9Data> GetIpInfoWithFallbackAsync(string ip)
{
try
{
var result = await Ip9Client.GetIpInfoAsync(ip);
if (result?.Ret == 200)
return result.Data;
}
catch (Exception ex)
{
Console.WriteLine($"ip9 查询失败: {ex.Message}");
}
// 降级方案一:太平洋网络 IP 查询(无需注册)
try
{
return await PconlineClient.GetIpInfoAsync(ip);
}
catch
{
// 降级方案二:返回默认值
return new Ip9Data
{
Ip = ip,
Country = "中国",
Province = "未知",
City = "未知"
};
}
}
五、对比:ip9.com.cn vs ip-api.com
| | |
|---|
| | |
| | |
| | |
| 区县级 | |
| 国家/省份/城市/区县/运营商/经纬度/邮编/区号 | |
| | |
| | |
六、总结
对于大多数国内业务开发者而言,ip9.com.cn 是一个零门槛、高精度、稳定可用的选择,C# 集成代码不到 30 行,开箱即用。
阅读原文:点击这里
该文章在 2026/9/10 15:01:39 编辑过