Python dnspython模块DNS解析实战:安装与A/MX/NS/CNAME记录查询
本文详细介绍Python中dnspython模块的安装方法及DNS解析实战。涵盖源码安装步骤,解析器类query方法的参数说明,以及A、MX、NS、CNAME等常见记录的查询代码实现。最后通过结合httplib2实现基于DNS轮询的业务IP监控示例,帮助开发者掌握自动化DNS处理技巧。
dnspython是一个基于Python语言开发的DNS工具包,支持多种记录类型查询、传输协议及ZONE信息的动态更新等功能。据称,该工具的功能可替代dig、nslookup等传统命令行工具。下文将详细阐述dnspython模块的具体使用方法。
dnspython源码安装
本节介绍dnspython模块的源码安装方式,当前使用的版本为1.16.0。

具体安装步骤如下:
wget https://www.dnspython.org/kits/1.16.0/dnspython-1.16.0.tar.gz

tar -zxvf dnspython-1.16.0.tar.gz

cd dnspython-1.16.0 python setup.py install
若看到红框所示信息,则表明安装已成功完成。

接下来,正式进入Python模块的功能讲解环节。
Python模块域名解析方法详解
在日常DNS测试中,手动操作往往较为繁琐,编写脚本自动化处理更为便捷,此时dnspython模块便派上用场。该库提供了丰富的DNS处理方法,其中最常用的是域名查询功能。dnspython库提供了一个解析器类(resolver),通过调用其query方法即可实现域名解析。关于query方法的参数说明如下:
query(self, qname, rdtype = 1, rdclass = 1, tcp = False, source = None, raise_on_no_answer = True, source_port = 0)
qname:待查询的域名。 rdtype:指定资源记录(RR)的类型。
所有支持的rdtype类型列表如下:

常用的记录类型包括以下几种:
A记录:将主机名解析为IP地址。 MX记录:邮件交换记录,用于定义邮件服务器的域名。 CNAME记录:别名记录,实现域名之间的映射。 NS记录:标记区域的域名服务器及授权子域。 PTR记录:反向解析,与A记录相反,将IP地址转换为主机名。 SOA记录:起始授权区标记,定义区域的相关信息。
rdclass:指定网络类型,可选值为CH或IN。其中IN为默认值,应用最为广泛。

tcp:指定查询是否启用TCP协议,默认不启用。
source与source_port:指定查询的源地址与源端口。
raise_on_no_answer:指定当查询无应答时是否触发异常,默认值为True。
接下来,我们将对几种常见的解析类型进行具体说明。
解析类型说明
A记录
#!/usr/local/bin/python38
# -*- coding: utf-8 -*-
import dns.resolver
domain = input('Please input an domain: ') #输入域名地址
A = dns.resolver.query(domain, 'A') #查询记录为A记录
for i in A.response.answer:
for j in i.items:
if j.rdtype == 1: #加判断,不然会出现AttributeError: 'CNAME' object has no attribute 'address'
print(j.address)
运行以下代码查看结果,此处以www.baidu.com域名为例:

通过上述操作,我们成功解析了www.baidu.com的域名。具体效果如下:

MX记录
#!/usr/local/bin/python38
# -*- coding: utf-8 -*-
import dns.resolver
domain = input('Input an domain : ')
MX = dns.resolver.query(domain, 'MX') # 指定解析类型为MX记录
for i in MX: # 遍历回应结果
print('MX preference =', i.preference, 'mail exchanger =', i.exchange)
运行以下代码查看结果,此处以qq.com域名为例:

从结果中可以看到preference值(优先级)和exchange值(交换地址)。默认优先级为10,MX记录可通过设置优先级来实现主辅服务器的配置。需要注意的是,“优先级”中的数字越小表示级别越高,且该优先级设置仅对MX记录有效。
NS记录
NS(Name Server)即域名服务器记录,用于指明由哪台服务器负责解析该域名。在注册域名时,通常会分配默认的DNS服务器,每个注册的域名均由特定的DNS域名服务器进行解析。
以下是实现NS记录查询的方法:
#!/usr/local/bin/python38
import dns.resolver
domain = input('Input an domain : ')
NS = dns.resolver.query(domain, 'NS')
for i in NS.response.answer:
for j in i.items:
print(j.to_text())
运行结果如下:

注意,此处仅限输入一级域名,例如baidu.com。如果输入二级或多级域名(如www.baidu.com),则会导致错误。我们可以尝试输入以验证这一问题:

CNAME记录
使用CNAME时,目标主机地址必须使用主机名,严禁使用IP地址。此外,主机名前不能包含其他前缀(如http://等),否则不被允许。
以下是使用CNAME记录方法的代码实现:
#!/usr/local/bin/python38
import dns.resolver
domain = input('Input an domain: ')
CNAME = dns.resolver.query(domain,'CNAME')
for i in CNAME.response.answer:
for j in i.items:
print(j.to_text())
运行结果如下:

运行结果显示www.a.shifen.com域名,这是www.baidu.com的别名指向。这相当于用子域名替代IP地址,其优点是当IP地址发生变化时,只需修改子域名的解析配置,而无需逐一更改所有IP地址的解析记录。
DNS域名轮询业务监控
大多数DNS解析器是一个域名对应一个IP地址,但通过DNS轮询技术,可以实现一个域名对应多个IP,从而实现最简单高效的负载均衡。然而,该方法最大的弊端在于当目标主机不可用时,无法自动将其剔除。因此,做好业务主机的服务可用性监控至关重要。

下面我们来实现域名解析,获取域名的所有A记录解析IP列表。
#!/usr/local/bin/python38
import dns.resolver
import httplib2
iplist = []
appdomain = "www.baidu.com"
def get_iplist(domain=""):
try:
A = dns.resolver.query(domain,"A")
except Exception as e:
print("dns resolver error:" + str(e))
return
for i in A.response.answer:
for j in i.items:
if j.rdtype == 1:
iplist.append(j.address)
return True
def checkip(ip):
checkurl = 'http://' + ip + ":80"
getcontent = ""
httplib2.socket.setdefaulttimeout(5)
conn = httplib2.Http()
try:
resp,getcontent=conn.request(checkurl)
finally:
if resp['status']== "200":
print(ip+"[OK]")
else:
print(ip+"[Error]")
if __name__ == "__main__":
if get_iplist(appdomain) and len(iplist) > 0:
for ip in iplist:
checkip(ip)
运行结果如下:

从结果可以看出,域名www.baidu.com解析出3个IP地址,且服务均正常。上述代码首先通过dns.resolver.query()方法获取业务域名的A记录信息,查询出所有IP地址列表;随后使用httplib2模块的request()方法以GET方式请求监控页面,以监控业务所有服务的IP是否运行正常。
总结
我们将IP地址转换为可读格式或单词后,即称为域名。在Python中,域名到IP地址的转换由dnspython模块管理。它支持多种记录类型、查询、传输以及动态更新ZONE信息的方法。感兴趣的朋友可以进一步查阅dnspython的源码。
到此,关于Python模块dnspython解析的文章介绍完毕。更多相关Python模块dnspython内容,请搜索本站以前的文章或继续浏览下面的相关文章。希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













