使用adns庫解析域名

1. adns、adns-python庫簡介html

adns庫是一個可進行異步非阻塞解析域名的庫,主要使用C語言編寫,在linux平臺下運行。使用adns庫進行域名解析效率很是,著名的開源網絡爬蟲larbin就使用adns庫進行域名解析。惋惜的是,adns庫沒有說明文檔。做者的意思是,adns.h這個文件便可說明這個庫的使用方法。很是遺憾,我不太懂dns解析過程當中所涉及到的各類細節知識,對C語言的掌握程度也沒能達到出神入畫的境界,因此,我不得不認可,光憑這個adns.h,我沒法知道應該如何使用adns庫這一強大的工具。python

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程序的。linux

目前,IPv4協議是互聯網上的主流IP層的協議。但因爲IPv4地址即將耗盡,各方都在積極推動IPv6協議。adns/adns-python協議也分爲IPv4版和IPv6版。下載地址以下git

adns IPv4版    adns IPv6版(1.4版可支持IPv6)    adns-python IPv4版    adns-python IPv6版github

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的庫安裝步驟相似。vim

安裝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. 能夠這樣解決:async

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)
相關文章
相關標籤/搜索