Python 如何实现根据主机名获取所有 IP 地址
本文将演示如何利用 Python 内置的 socket 模块,将指定的主机名或域名快速解析为所有可访问的 IP 地址。通过标准化接口调用与数据清洗,可自动过滤无效记录并输出清晰列表,轻松应对爬虫调度、负载均衡检测与自动化运维任务。
核心原理与适用场景
在自动化运维、流量分发或安全审计中,经常需要批量获取某台服务器或域名的全部物理节点地址。现代互联网普遍采用多 IP 轮询或 Anycast 技术,单一域名往往对应多个 IPv4 甚至 IPv6 地址。Python 提供了高效的底层网络接口,无需安装第三方库即可完成主机名到 IP 映射的批量提取。
第1步:导入 socket 标准库
准备阶段只需引入 Python 内置的 socket 模块。该库封装了 BSD Socket 接口,支持跨平台进行 TCP/UDP 连接、主机名解析与网络配置查询。由于是标准库,任何安装了基础 Python 环境的系统均可直接使用,无需额外执行 pip install。
第2步:调用 getaddrinfo 获取地址元组
解析的核心入口为 socket.getaddrinfo() 函数。它接受目标主机名、服务端口、地址族(Address Family)及协议类型作为参数,返回一个包含五个元素的嵌套元组列表。每个元组的结构为:(family, socktype, proto, canonname, sockaddr)。其中 sockaddr 字段直接承载了对应的网络地址与端口信息。
第3步:提取并去重纯 IP 地址
原始返回值包含大量冗余协议标识,实际业务通常只需要纯净的 IP 字符串。通过列表推导式遍历返回结果,定位索引 [4] 获取元组形式的地址,再取索引 [0] 分离出 IP 部分。结合字典键值去重特性,可保留首次出现的顺序并剔除重复节点。
完整代码与运行验证
以下为适配 Python 3.x 的现代写法,包含容错机制与结构化输出:
import socket
def get_all_ips(hostname):
try:
# 限制 AF_INET 仅查询 IPv4,移除该参数可同时获取 IPv6
results = socket.getaddrinfo(hostname, None, socket.AF_INET, socket.SOCK_STREAM)
# 提取地址元组中的 IP 部分,并利用 dict.fromkeys 保持顺序去重
ip_list = list(dict.fromkeys(item[4][0] for item in results))
return ip_list
except socket.gaierror as e:
return None, str(e)
target_host = "www.google.com"
ips, err = get_all_ips(target_host)
if ips:
for idx, ip in enumerate(ips, 1):
print(f"{idx}: {ip}")
else:
print(f"解析异常: {err}")
脚本执行后将打印格式化的 IP 列表,控制台输出参考如下:
1: 74.125.128.106
2: 74.125.128.147
3: 74.125.128.99
4: 74.125.128.103
5: 74.125.128.104
异常处理与常见排错
- DNS 解析超时或拒绝:若目标主机不存在或 DNS 服务器不可达,
getaddrinfo会抛出socket.gaierror。务必使用try...except捕获,避免程序中断。 - CNAME 别名链过长:部分 CDN 或云服务会设置多级 CNAME 指向。本方法自动跟随解析链直至根 IP,不受别名层数影响,但频繁请求可能触发限流。
- IPv6 地址格式兼容:当未指定
AF_INET且系统支持双栈时,返回列表中将包含括号包裹的 IPv6 地址。后续接入传统网关前需确认接收端是否支持十六进制表示法。
总结
利用内置 socket 接口进行批量地址查询是兼顾性能与稳定性的首选方案。掌握参数调优与异常捕获逻辑后,开发者可直接将其嵌入代理池构建、健康检查脚本或资产扫描工具中。以上就是 Python 实现根据主机名字获取所有 IP 地址的详细内容,更多关于 socket 模块高级用法与网络自动化配置的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













