1. adns、adns-python库简介
adns库是一个可进行异步非阻塞解析域名的库,主要使用C语言编写,在linux平台下运行。使用adns库进行域名解析效率非常,著名的开源网络爬虫larbin就使用adns库进行域名解析。可惜的是,adns库没有说明文档。作者的意思是,adns.h这个文件即可说明这个库的使用方法。非常遗憾,我不太懂dns解析过程中所涉及到的各种细节知识,对C语言的掌握程度也没能达到出神入画的境界,所以,我不得不承认,光凭这个adns.h,我无法知道应该如何使用adns库这一强大的工具。
adns-python库是adns库的python扩展。在python程序中,可调用其他语言写好的函数。由于adns比较优秀,所以有人为它开发了一个python扩展程序。查了下Python扩展程序的相关内容,了解到写这种扩展程序是有模板的。首先,应该在file1.c文件中把核心函数写好。然后,再开发一个为这些核心文件开发python扩展模块文件(也为一个.c文件)。通常,扩展模块至少应该包含三个部分:导出函数、方法列表和初始化函数。python扩展模块保存在file2.c文件中。最后,通过编译,将这些核心函数编译成一个python程序可调用的函数。这么说起来比较抽象,可以参考这篇文章(http://www.ibm.com/developerworks/cn/linux/l-pythc/)或者《python核心编程(第二版)》中的第22章“扩展python”来清楚地了解Python是如何扩展C程序的。
目前,IPv4协议是互联网上的主流IP层的协议。但由于IPv4地址即将耗尽,各方都在积极推进IPv6协议。adns/adns-python协议也分为IPv4版和IPv6版。下载地址如下
adns IPv4版 adns IPv6版(1.4版可支持IPv6) adns-python IPv4版 adns-python IPv6版
2.python-adns库的安装
因为我使用python进行开发,所以使用adns-python作为我的库。由于dns解析的核心函数都在adns中,所以必须首先安装adns库后,adns-python才可以安装成功。如果想进行IPv6的地址解析,必须安装支持IPv6地址解析的adns库和adns-python库。支持IPv4的库不可解析IPv6的域名地址,但支持IPv6的库可同时支持解析IPv4和IPv6的域名地址。adns库的源代码中的INSTALL文件有说明如何安装adns库,adns-python中的README文件中也有说明如何安装adns-python库。支持IPv4和支持IPv6的库安装步骤类似。
安装adns库:
$ ./configure [--disable-dynamic] [--prefix=...]
$ make
# make install
注意,make install这一命令需要有root权限
安装adns-python库:
$ python setup.py build (如果提示没有python.h文件,请安装python-devel。 命令为: yum install python-devel)
# python setup.py install
注意,python setup.py install这一命令需要有root权限
3. python-adns库的使用
这里有一个利用adns-python库写的dns解析的代码。起先我不太明白为什么作者就能知道应该这样使用这些库中的函数,因为adns-python库与adns库一样,没有说明文档。后来,经高人指点,发现adns-python库中有一个ADNS.py文件,这个文件中QueryEngine类,这个类中定义的函数即给我们示范了库中提供的常用函数的使用方法。至于这些常用函数具有什么样的功能,应该如何使用等问题,只能有去源代码中找寻答案啦~~
如果代码报错,提示:libadns.so.1: cannot open shared object file: No such file or directory. 可以这样解决:
1. vim /etc/ld.so.conf
2. 添加该lib所在的路径 (libadns.so.1的路径通常中/usr/local/lib )
3. ldconfig
这是因为libadns.so.1不在默认共享库路径下。具体可参看:http://www.cnblogs.com/xuxm2007/archive/2010/08/10/1796254.html
把人家的代码贴在这里好啦:
#!/usr/bin/python
#
import adns
from time import time
class AsyncResolver(object):
def __init__(self, hosts, intensity=100):
"""
hosts: a list of hosts to resolve
intensity: how many hosts to resolve at once
"""
self.hosts = hosts
self.intensity = intensity
self.adns = adns.init()
def resolve(self):
""" Resolves hosts and returns a dictionary of { 'host': 'ip' }. """
resolved_hosts = {}
active_queries = {}
host_queue = self.hosts[:]
def collect_results():
for query in self.adns.completed():
answer = query.check()
host = active_queries[query]
del active_queries[query]
if answer[0] == 0:
ip = answer[3][0]
resolved_hosts[host] = ip
elif answer[0] == 101: # CNAME
query = self.adns.submit(answer[1], adns.rr.A)
active_queries[query] = host
else:
resolved_hosts[host] = None
def finished_resolving():
return len(resolved_hosts) == len(self.hosts)
while not finished_resolving():
while host_queue and len(active_queries) < self.intensity:
host = host_queue.pop()
query = self.adns.submit(host, adns.rr.A)
active_queries[query] = host
collect_results()
return resolved_hosts
if __name__ == "__main__":
host_format = "www.host%d.com"
number_of_hosts = 20000
hosts = [host_format % i for i in range(number_of_hosts)]
ar = AsyncResolver(hosts, intensity=500)
start = time()
resolved_hosts = ar.resolve()
end = time()
print "It took %.2f seconds to resolve %d hosts." % (end-start, number_of_hosts)