一、核心思路
- 呼叫外部 IP 定位 HTTP API(GET 請求)。
- 解析回應(JSON/HTML/純文字)。
- 提取省份、城市、ISP 等欄位。
二、主流免費 API 對比
| 服務商 | 介面網址 | 回應格式 | 頻率限制 | 備註 |
| 騰訊 IP 分享計劃 | https://ip.qq.com/cgi-bin/searchip?searchip1=IP | HTML (GBK) | 不公開 | 需解析 HTML,較脆弱 |
| 新浪 IP 查詢 | https://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=IP | JSON | 較寬鬆 | 推薦,結構化好解析 |
| 淘寶 IP 庫 | https://ip.taobao.com/service/getIpInfo.php?ip=IP | JSON | QPS 限制 | 資料準確,官方已停止公開服務,內網可用 |
| ip-api.com | https://ip-api.com/json/IP?lang=zh-CN | JSON | 45 req/min (免費) | 國際通用,支援 HTTPS |
三、完整實作:新浪 JSON API 範例
public class IpLocationUtil {
private static final String SINA_API = "https://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=";
public static String getLocation(String ip) {
String urlStr = SINA_API + ip;
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new URL(urlStr).openStream(), StandardCharsets.UTF_8))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) sb.append(line);
// 解析 JSON(這裡用簡易字串處理,實際建議用 Jackson/Gson)
String json = sb.toString();
if (json.contains("\"ret\":1")) return "查詢失敗";
String country = extract(json, "\"country\":\"", "\"");
String province = extract(json, "\"province\":\"", "\"");
String city = extract(json, "\"city\":\"", "\"");
String isp = extract(json, "\"isp\":\"", "\"");
return String.format("%s %s %s %s", country, province, city, isp).trim();
} catch (IOException e) {
return "查詢異常: " + e.getMessage();
}
}
private static String extract(String src, String start, String end) {
int s = src.indexOf(start);
if (s == -1) return "";
s += start.length();
int e = src.indexOf(end, s);
return e == -1 ? "" : src.substring(s, e);
}
public static void main(String[] args) {
System.out.println(getLocation("8.8.8.8")); // Google DNS
System.out.println(getLocation("114.114.114.114")); // 114 DNS
}
}
四、生產級強化建議
- 連線池與超時:使用 HttpClient (Apache HttpComponents 5 / OkHttp) 設定連線/讀取逾時、連線池複用。
- 快取策略:IP 歸屬地變動極低,引入 Caffeine/Redis 本地/分散式快取,Key 為 IP,TTL 7-30 天。
- 異步非阻塞:高併發場景改用 CompletableFuture 或 Reactor 非阻塞呼叫。
- 容錯降級:多 API 輪詢、熔斷器、失敗回傳預設值(如「未知地區」)。
- 離線資料庫:極高效能需求可採用 MaxMind GeoIP2 / ip2region 本地資料庫,微秒級查詢。
五、注意事項
- 免費 API 多為 HTTP,敏感業務請用 HTTPS 付費版。
- 騰訊介面回傳 GBK 編碼,讀取時需指定
GBK 或 GB2312。
- 內網 IP (10.x、172.16-31、192.168) 無公網定位意義,需特殊處理。
- 遵守服務商條款,勿濫用,建議申請正式 Key。