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)
