关于dns:dnspython和python对象

dnspython and python objects

我正在尝试使用dnspython库,并对查询此页上MX记录的示例感到有点困惑:www.dnspython.org/examples.html:

1
2
3
4
5
import dns.resolver

answers = dns.resolver.query('dnspython.org', 'MX')
for rdata in answers:
    print 'Host', rdata.exchange, 'has preference', rdata.preference

在python cli中,dir(answers)给了我:

1
['__class__', '__delattr__', '__delitem__', '__delslice__', '__dict__', '__doc__', '__getattr__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__iter__', '__len__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'expiration', 'qname', 'rdclass', 'rdtype', 'response', 'rrset']

有两件事让我困惑(相关的):

  • 对answers对象进行迭代。示例中的RData是什么?
  • 答案的属性或方法都不符合交换或偏好。显然,RData不仅是答案的简单别名,而且我不理解这些属性的来源。

  • 到目前为止,我还没有看过dns.resolver——我只是把它添加到了不断增长的需要检查的项目列表中。我猜rdata指的是资源记录类型特定的数据,如RFC1035第4.1.3节所述。除了查询和头文件之外,DNS请求的响应还包含三个数据部分:

  • 答案
  • 权威名称服务器记录
  • 其他资源记录
  • 从外观上看,dns.resolver.query()正在返回第一部分。在这种情况下,应答部分中的每个资源记录将根据记录类型具有不同的属性。在这种情况下,您要求输入MX个记录,因此这些记录应该具有您所拥有的属性-exchangepreference。这些在RFC1035第3.3.9节中进行了描述。

    我怀疑dns.resolver正在凌驾于__getattr__或类似于你所看到的魔法的东西之上,所以你不会直接看到dir()中的字段。很可能您可以安全地使用RFC1035中定义的属性。我明天一定要检查一下,因为我需要一个适合Python的DNS子系统。

    感谢您提及此模块并与DNS一起玩得开心。如果你真的深入研究它是如何工作的,这真的很有趣。我仍然认为,这是一个早期的表达,平静的事情是所有愤怒的这些天;)


    答案是可重复的,正如它的"重复"方法所指出的那样。把答案看作是一个RDatas列表。

    您可以尝试这样做,从答案中获取1个RData:

    1
    answers.__iter__().next()


    在示例代码中,answers是一个包含零个或多个项的可重复对象,这些项依次分配给rdata。要查看单个响应的属性,请尝试:

    1
    dir(answers[0])

    如果您使用的是python 2.6,那么获得任何iterable的第一个项目(例如这里的answers)的"正确"方法是next(iter(answers));如果您希望避免当answers为空iterable时出现异常,那么next(iter(answers), somevalue)将返回somevalue,而不是提升StopIteration。如果你在2.5,那么你就用iter(answers).next(),但是如果你需要处理一个可能是空的iterable,你就必须在try/except StopIteration:语句中使用它。