我正在尝试获取所有IP地址:earth.all.vpn.airdns.org 在Python中:
def hostnamesToIps(hostnames):
ip_list = []
for hostname in hostnames:
try:
ais = socket.getaddrinfo(hostname, None)
for result in ais:
#print (result[4][0])
ip_list.append(result[-1][0])
except:
eprint("Unable to get IP for hostname: " + hostname)
return list(set(ip_list))
(f eprint是打印错误的功能)。 输出给了我29个地址。
但是当我这样做时:
nslookup earth.all.vpn.airdns.org
我得到大约100个人。
如何在python中实现这一点?为什么我没有得到所有的“getaddrinfo”?
此行为仅在使用Windows(python 3)时出现。当我在Linux(python 2.7)上执行代码时,它给出了与使用nslookup相同的结果。
信息:如答案所述,它不依赖于系统。
在不改变任何内容的情况下,nslookup和getaddrinfo的结果现在都是一样的。
答案 0 :(得分:3)
像dig
,host
和nslookup
这样的工具直接使用UDP / TCP和他们自己的DNS查询实现查询默认DNS服务器,而Python的socket
模块使用操作系统的DNS查找接口,通常使用更复杂的查找机制,例如涉及dns缓存,主机文件,域后缀,链接本地名称解析等。
strace
表明Python的socket.getaddrinfo
最终使用netlink(AF_NETLINK)套接字来查询系统的DNS查找(Ubuntu 12.04上的Python 2.7)。但是,nslookup
从/etc/resolv.conf
读取默认DNS服务器并在端口53上打开UDP套接字。
我认为您有两个原因可以获得不同的条目:
nslookup
始终检索“新鲜”结果。此外,nslookup
可能会产生与系统解析程序略有不同的DNS查询(产生另一个答案)。这可以通过Wireshark检查,但我现在就离开了。
另一个问题可能是在使用UPD时截断DNS响应。如果有大量条目,它们将不适合单个UDP包,因此答案包含截断标志。它取决于客户端通过TCP套接字重新发送DNS查询以检索所有结果。(截断的答案实际上是空的)。
编辑关于缓存/易失性的说明
即使不匹配不是由于您的本地DNS缓存,也可能是由于服务器端缓存。我尝试了几个DNS服务器,并且都为该特定名称提供了不同的结果。这意味着由于生存时间(TTL)内的DNS更改,它们不同步。