如何用Python调用IPv6检测API?
要调用IPv6检测API,关键在于选择合适的API服务并使用Python的requests库进行HTTP请求。以下是经过验证的实用方法,涵盖主流IPv6检测API的调用方式、参数设置及错误处理。
一、常用IPv6检测API调用示例
1. 基础IPv6地址检测API
API服务:提供IPv6地址获取和基础检测功能
import requests
def check_ipv6_address():
"""检测客户端IPv6地址"""
url = "https://api.xunjinlu.fun/api/ip/ipv6.php" # IPv6地址获取API
try:
response = requests.get(url, timeout=5)
response.raise_for_status() # 检查HTTP错误
data = response.json()
if data["code"] == 200:
print(f"检测到IPv6地址: {data['data']['ipv6']}")
print(f"检测时间: {data['data']['timestamp']}")
return data['data']['ipv6']
else:
print(f"API返回错误: {data['message']}")
return None
except requests.exceptions.RequestException as e:
print(f"网络请求失败: {str(e)}")
return None
except ValueError as e:
print(f"JSON解析失败: {str(e)}")
return None
2. 专业IPv6归属地查询API
API服务:IP数据云提供高覆盖率的IPv6归属地查询
import requests
import ipaddress
def normalize_ipv6(ip_str):
"""标准化IPv6格式,处理简写"""
try:
return str(ipaddress.ip_address(ip_str))
except ValueError:
print(f"无效的IPv6地址: {ip_str}")
return None
def query_ipv6_location(ipv6_address, api_key="your_api_key"):
"""查询IPv6地址归属地信息"""
# 标准化IPv6地址格式
normalized_ip = normalize_ipv6(ipv6_address)
if not normalized_ip:
return None
url = "https://api.ipdatacloud.com/v2/query"
params = {
"ip": normalized_ip,
"key": api_key
}
try:
response = requests.get(url, params=params, timeout=3)
response.raise_for_status()
result = response.json()
# 检查IPv6数据是否完整
if result.get("city") is None and isinstance(ipaddress.ip_address(normalized_ip), ipaddress.IPv6Address):
result["tips"] = "该IPv6段暂未分配具体地址,建议结合ASN分析"
return result
except requests.exceptions.RequestException as e:
print(f"API请求失败: {str(e)}")
return None
except ValueError as e:
print(f"JSON解析失败: {str(e)}")
return None
3. IPv6网站支持性检测
API服务:检测网站是否真正支持IPv6访问
import requests
import socket
from urllib.parse import urlparse
def check_website_ipv6_support(url):
"""检测网站是否支持IPv6访问"""
# 提取域名
domain = urlparse(url).netloc
# 检查AAAA记录
try:
aaaa_records = socket.getaddrinfo(domain, None, socket.AF_INET6)
if not aaaa_records:
print(f"{url} 不支持IPv6: 无AAAA记录")
return False
except Exception as e:
print(f"DNS查询失败: {str(e)}")
return False
# 提取IPv6地址
ipv6_address = aaaa_records
print(f"发现AAAA记录: {ipv6_address}")
# 检查IPv6连通性
try:
# 使用curl风格的请求测试
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.41"}
response = requests.get(url, timeout=3, verify=False, headers=headers)
if response.status_code == 200:
print(f"{url} 支持IPv6访问,响应状态码: {response.status_code}")
return True
else:
print(f"{url} 不支持IPv6访问,响应状态码: {response.status_code}")
return False
except Exception as e:
print(f"连接失败: {str(e)}")
return False
二、API调用关键技巧
1. IPv6地址标准化处理
为什么需要:IPv6地址常有简写形式(如2400:3200::1),需转换为完整格式才能正确查询
import ipaddress
def normalize_ipv6(ip_str):
"""标准化IPv6地址格式"""
try:
ip_obj = ipaddress.ip_address(ip_str)
return str(ip_obj) if isinstance(ip_obj, ipaddress.IPv6Address) else ip_str
except ValueError as e:
raise ValueError(f"IP格式非法:{ip_str},错误:{e}")
2. 错误处理与重试机制
最佳实践:添加重试机制应对API不稳定情况
import time
from requests.exceptions import RequestException
def api_call_with_retry(url, max_retries=3, retry_delay=1):
"""带重试机制的API调用"""
for attempt in range(max_retries):
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
return response.json()
except RequestException as e:
if attempt == max_retries - 1:
print(f"API调用失败,已达到最大重试次数: {str(e)}")
return None
print(f"API调用失败,{retry_delay}秒后重试... 错误: {str(e)}")
time.sleep(retry_delay)
3. IPv6网络连通性验证
关键点:仅检查AAAA记录不够,需验证实际连通性
import subprocess
def ping_ipv6(ipv6_address):
"""使用ping命令测试IPv6连通性"""
try:
output = subprocess.check_output(["ping", "-c", "1", "-6", ipv6_address])
return b"1 received" in output
except subprocess.CalledProcessError:
return False
三、实用建议
1. 选择API服务的考量因素
- 覆盖率:专业服务的IPv6库覆盖率可达95%以上,而IPv4接近100%
- 定位精度:IPv6通常提供省级/市级定位,而IPv4可达区县级/街道级
- 响应速度:优质API的P95响应延迟≤100ms,适合高并发场景
- 免费额度:多数API提供100-1000次/天的免费调用额度
2. 常见问题解决方案
问题:API返回"IP格式非法"
解决方案:使用ipaddress模块标准化IPv6地址格式
问题:查询结果为空
解决方案:IPv6新分配网段可能存在信息空白,尝试结合ASN分析
问题:响应超时
解决方案:设置合理超时时间(3-5秒),并添加重试机制
3. 完整调用流程
1. **获取IPv6地址**:使用基础API获取目标IPv6地址
2. **标准化处理**:将IPv6地址转换为完整格式
3. **归属地查询**:调用专业API获取地理位置信息
4. **连通性验证**:使用ping或curl测试实际连通性
5. **结果分析**:综合判断IPv6原生度和网络质量
四、高级应用示例
场景:自动检测家庭宽带IPv6地址变化并更新CDN配置
import requests
import time
def get_current_ipv6():
"""获取当前外网IPv6地址"""
return requests.get("https://v6.ident.me").text
def update_cdn_config(ipv6_address, api_key, api_secret):
"""更新CDN控制台的IPv6地址"""
url = "https://user.cdn1.vip/v1/sites/your_site_id"
data = {
"backend": [{"index": 0, "state": "up", "addr": ipv6_address, "weight": "1"}]
}
headers = {
"api-key": api_key,
"api-secret": api_secret
}
return requests.put(url, json=data, headers=headers)
# 主循环:每分钟检测一次IPv6地址变化
while True:
current_ip = get_current_ipv6()
# 假设上次记录的IP已存储在last_ip变量中
if current_ip != last_ip:
print(f"IPv6地址已变化: {last_ip} → {current_ip}")
response = update_cdn_config(current_ip, "your_api_key", "your_api_secret")
if response.status_code == 200:
print("CDN配置更新成功")
last_ip = current_ip
else:
print(f"更新失败: {response.text}")
time.sleep(60) # 每分钟检测一次
重要提示:在实际应用中,不要仅依赖单一API。建议结合多个API服务进行交叉验证,确保结果的准确性。对于企业级应用,可考虑部署离线IP数据库,避免外网延迟和API调用限制。同时,注意API的调用频率限制,避免因过度调用导致服务中断。