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