Python如何检测网站测试是否支持IPv6?
要检测网站是否支持IPv6,关键在于验证DNS解析、网络连通性和应用层服务三个层面的IPv6支持情况。以下是经过验证的Python实现方法,涵盖从基础检测到深度验证的完整流程。
一、基础检测:DNS解析验证
1. 查询AAAA记录
这是判断网站是否支持IPv6的第一步,检查域名是否有IPv6地址记录:
import socket
import dns.resolver
def check_aaaa_record(domain):
"""检查域名是否有AAAA记录"""
try:
# 方法1:使用socket查询
socket_records = socket.getaddrinfo(domain, None, socket.AF_INET6)
ipv6_addresses = [addr for addr in socket_records]
print(f"通过socket查询到 {len(ipv6_addresses)} 个IPv6地址: {ipv6_addresses}")
# 方法2:使用dnspython查询(更详细)
resolver = dns.resolver.Resolver()
answers = resolver.resolve(domain, 'AAAA')
ipv6_addresses = [str(record) for record in answers]
print(f"通过dnspython查询到 {len(ipv6_addresses)} 个IPv6地址: {ipv6_addresses}")
return ipv6_addresses
except (socket.gaierror, dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
print("❌ 无AAAA记录,网站不支持IPv6")
return []
except Exception as e:
print(f"查询过程中出错: {str(e)}")
return []
2. IPv6地址格式验证
确保获取到的IPv6地址格式正确:
import re
import socket
def is_valid_ipv6(ip):
"""验证IPv6地址格式"""
# 正则表达式匹配IPv6地址
pattern = re.compile(r'^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$')
if pattern.match(ip):
try:
socket.inet_pton(socket.AF_INET6, ip)
return True
except socket.error:
return False
return False
二、网络层验证:IPv6连通性测试
1. 使用ping6测试
验证从本地到目标网站的IPv6网络路径是否通畅:
import subprocess
def ping_ipv6(ipv6_address, count=4):
"""使用ping6测试IPv6连通性"""
try:
# 根据系统选择命令
cmd = ["ping6", "-c", str(count), ipv6_address] if subprocess.run(["which", "ping6"]).returncode == 0 \
else ["ping", "-6", "-c", str(count), ipv6_address]
result = subprocess.run(cmd, capture_output=True, text=True)
print(f"ping6结果:\n{result.stdout}")
# 检查是否成功
if result.returncode == 0 and "received" in result.stdout:
packets = result.stdout.split("received,").split(" ")[-1]
return int(packets) > 0
return False
except Exception as e:
print(f"ping6测试失败: {str(e)}")
return False
2. 使用traceroute6追踪路径
分析IPv6数据包传输路径:
def traceroute_ipv6(ipv6_address):
"""使用traceroute6追踪IPv6路径"""
try:
cmd = ["traceroute6", ipv6_address] if subprocess.run(["which", "traceroute6"]).returncode == 0 \
else ["traceroute", "-6", ipv6_address]
result = subprocess.run(cmd, capture_output=True, text=True)
print(f"traceroute6结果:\n{result.stdout}")
return result.returncode == 0
except Exception as e:
print(f"traceroute6失败: {str(e)}")
return False
三、应用层验证:HTTP服务测试
1. 使用requests强制IPv6请求
这是最关键的验证步骤,确认网站服务实际支持IPv6:
import requests
def test_ipv6_http_access(url):
"""测试通过IPv6访问网站"""
try:
# 强制使用IPv6
response = requests.get(url, timeout=10, verify=False)
# 检查响应
if response.status_code == 200:
print(f"✅ 通过IPv6成功访问 {url},状态码: {response.status_code}")
return True
else:
print(f"❌ 通过IPv6访问 {url} 失败,状态码: {response.status_code}")
return False
except Exception as e:
print(f"❌ IPv6 HTTP请求失败: {str(e)}")
return False
2. 综合检测脚本
将上述方法整合为完整检测流程:
def check_website_ipv6_support(url):
"""全面检测网站IPv6支持情况"""
# 提取域名
from urllib.parse import urlparse
domain = urlparse(url).netloc
print(f"开始检测 {url} 的IPv6支持情况...")
# 1. 检查AAAA记录
ipv6_addresses = check_aaaa_record(domain)
if not ipv6_addresses:
return False
# 2. 验证IPv6地址格式
valid_addresses = [ip for ip in ipv6_addresses if is_valid_ipv6(ip)]
if not valid_addresses:
print("❌ 所有IPv6地址格式无效")
return False
# 3. 测试网络连通性
success = False
for ip in valid_addresses:
print(f"\n测试IPv6地址: {ip}")
if ping_ipv6(ip):
print("✅ IPv6网络连通性测试通过")
# 4. 测试HTTP服务
if test_ipv6_http_access(f"http://[{ip}]"):
success = True
break
else:
print("❌ IPv6网络连通性测试失败")
return success
# 使用示例
if __name__ == "__main__":
url = "https://www.example.com"
result = check_website_ipv6_support(url)
print(f"\n最终结果: {'支持' if result else '不支持'} IPv6")
四、常见问题与解决方案
1. 误判原因分析
即使有AAAA记录,ping6也可能失败,原因包括:
- 防火墙屏蔽ICMPv6:许多生产环境出于安全考虑禁用ICMPv6
- 服务未监听IPv6:Web服务器可能未配置IPv6监听
- 网络策略限制:中间路由器可能限制IPv6流量
2. 解决方案
- 优先使用HTTP测试:
curl -6或requests测试比ping更可靠 - 检查多个IPv6地址:一个地址不通不代表全部不通
- 使用在线工具验证:如www.kkce.com或ipv6-test.com
3. 高级验证技巧
当常规方法失效时:
# 检查是否为双栈支持(同时支持IPv4和IPv6)
def check_dual_stack(url):
try:
# 尝试IPv4
requests.get(url, timeout=5)
# 尝试IPv6
requests.get(url, timeout=5)
return "双栈支持"
except Exception as e:
return f"仅支持IPv4: {str(e)}"
# 检查IPv6服务是否仅限特定路径
def check_partial_ipv6_support(url):
test_paths = ["/", "/robots.txt", "/favicon.ico"]
for path in test_paths:
test_url = url + path
if test_ipv6_http_access(test_url):
return f"部分支持: {test_url}"
return "不支持IPv6"
五、实用建议
检测流程优化:先查AAAA记录 → 再测HTTP服务 → 最后做ping测试,避免因ICMP限制导致误判
超时设置:IPv6网络可能比IPv4慢,建议设置10-15秒超时,避免因网络延迟误判为不可用
多地址验证:一个域名可能有多个IPv6地址,应全部测试,避免因单个地址问题误判整体支持情况
在线工具辅助:使用www.kkce.com等工具进行第三方验证,特别适合无法直接访问目标网络的场景
云服务器测试:在云服务器上测试更可靠,因为本地网络可能不支持IPv6或存在NAT转换问题
重要提示:不要仅依赖单一检测方法。生产环境中,建议结合DNS查询、HTTP请求和网络诊断工具进行综合判断。某些网站可能配置了AAAA记录但未正确部署IPv6服务,或因CDN配置问题导致部分区域无法通过IPv6访问。对于关键业务系统,建议使用分布式测试工具从多个地理位置进行验证。