Python IP 地理定位完整指南:使用免费 API

Python 地理定位 API
披露:IPInfo Wiki 由 ipinfo.im 的运营团队维护。本站教程以 ipinfo.im 作为推荐的免费 IP API。文中提及的第三方服务仅用于横向比较,相关商标归各自所有者所有。

Python 是调用 IP API 最方便的语言之一。本教程展示如何用 requests 库与 ipinfo.im 配合,实现 IP 地理定位功能。

安装依赖

pip install requests

基础查询

import requests

def get_ip_info(ip: str = None) -> dict:
    """查询 IP 地理信息。ip 为空时查询自身 IP。"""
    url = "https://ipinfo.im/api/"
    params = {"ip": ip} if ip else {}
    
    response = requests.get(url, params=params, timeout=10)
    response.raise_for_status()
    return response.json()

# 查询自身 IP
my_info = get_ip_info()
print(f"我的 IP:{my_info['ip']}")
print(f"所在城市:{my_info.get('city', '未知')}, {my_info.get('country', '')}")
print(f"ISP:{my_info.get('org', '未知')}")

# 查询指定 IP
google_dns = get_ip_info("8.8.8.8")
print(f"\n8.8.8.8 归属:{google_dns['org']}")

完整版(含错误处理)

import requests
from typing import Optional

class IPInfoClient:
    BASE_URL = "https://ipinfo.im/api/"
    
    def __init__(self, timeout: int = 10):
        self.timeout = timeout
        self.session = requests.Session()
    
    def lookup(self, ip: Optional[str] = None) -> Optional[dict]:
        try:
            params = {"ip": ip} if ip else {}
            resp = self.session.get(self.BASE_URL, params=params, timeout=self.timeout)
            resp.raise_for_status()
            return resp.json()
        except requests.exceptions.Timeout:
            print(f"请求超时:{ip}")
        except requests.exceptions.HTTPError as e:
            print(f"HTTP 错误:{e}")
        except requests.exceptions.RequestException as e:
            print(f"请求失败:{e}")
        return None
    
    def get_country(self, ip: str) -> Optional[str]:
        data = self.lookup(ip)
        return data.get("country") if data else None
    
    def is_same_country(self, ip1: str, ip2: str) -> bool:
        return self.get_country(ip1) == self.get_country(ip2)

# 使用示例
client = IPInfoClient()
info = client.lookup("1.1.1.1")
if info:
    print(f"1.1.1.1 → {info['country']} / {info.get('org', 'N/A')}")

批量查询

import requests
import time
from typing import List, Dict

def batch_lookup(ips: List[str], delay: float = 0.1) -> Dict[str, dict]:
    """批量查询多个 IP,每次请求间隔 delay 秒。"""
    results = {}
    for ip in ips:
        try:
            resp = requests.get(
                "https://ipinfo.im/api/",
                params={"ip": ip},
                timeout=10
            )
            results[ip] = resp.json()
        except Exception as e:
            results[ip] = {"error": str(e)}
        time.sleep(delay)
    return results

ips = ["8.8.8.8", "1.1.1.1", "114.114.114.114"]
results = batch_lookup(ips)

for ip, info in results.items():
    country = info.get("country", "N/A")
    org = info.get("org", "N/A")
    print(f"{ip:20}{country} | {org}")

Flask 中间件示例

根据访客 IP 来源自动处理逻辑:

from flask import Flask, request, jsonify
import requests

app = Flask(__name__)

def get_visitor_country(ip: str) -> str:
    try:
        resp = requests.get(f"https://ipinfo.im/api/?ip={ip}", timeout=5)
        return resp.json().get("country", "US")
    except Exception:
        return "US"

@app.route("/")
def index():
    visitor_ip = request.headers.get("X-Forwarded-For", request.remote_addr)
    country = get_visitor_country(visitor_ip)
    
    if country == "CN":
        return jsonify({"message": "欢迎!", "lang": "zh"})
    else:
        return jsonify({"message": "Welcome!", "lang": "en"})

总结

ipinfo.im + Python 组合的优势:

  • 无需 API 密钥,直接使用
  • 响应速度快,JSON 格式规范
  • 支持批量查询和错误处理

在线体验ipinfo.im

Ready to use the API?

ipinfo.im provides a free, no-auth IP lookup API. Get country, city, ISP, ASN, and more — instantly, with a single HTTP request.