2

我正在通过 dig 处理来自 DNSBL 的数千个域名列表,创建一个包含 URL 和 IP 的 CSV。这是一个非常耗时的过程,可能需要几个小时。我的服务器的 DNSBL 每十五分钟更新一次。有没有办法可以增加我的 Python 脚本的吞吐量以跟上服务器的更新?

编辑:脚本,根据要求。

import re
import subprocess as sp

text = open("domainslist", 'r')
text = text.read()
text = re.split("\n+", text)

file = open('final.csv', 'w')

for element in text:
        try:
            ip = sp.Popen(["dig", "+short", url], stdout = sp.PIPE)
            ip = re.split("\n+", ip.stdout.read())
            file.write(url + "," + ip[0] + "\n")
        except:
            pass
4

4 回答 4

2

这里的大部分时间都花在了对 的外部调用上dig,所以为了提高速度,你需要多线程。这将允许您同时运行多个调用dig。参见例如:Python Subprocess.Popen from a thread。或者,您可以使用 Twisted ( http://twistedmatrix.com/trac/ )。

编辑:你是对的,其中大部分是不必要的。

于 2010-06-22T00:57:25.980 回答
2

好吧,可能是名称解析花了你这么长时间。如果你把它排除在外(即,如果 dig 以某种方式很快返回),Python 应该能够轻松处理数千个条目。

也就是说,您应该尝试线程方法。这将(理论上)同时解析多个地址,而不是顺序解析。您也可以继续使用 dig ,并且为此修改下面的示例代码应该很简单,但是,为了让事情变得有趣(并且希望更 Pythonic),让我们为此使用现有模块:dnspython

所以,安装它:

sudo pip install -f http://www.dnspython.org/kits/1.8.0/ dnspython

然后尝试以下操作:

import threading
from dns import resolver

class Resolver(threading.Thread):
    def __init__(self, address, result_dict):
        threading.Thread.__init__(self)
        self.address = address
        self.result_dict = result_dict

    def run(self):
        try:
            result = resolver.query(self.address)[0].to_text()
            self.result_dict[self.address] = result
        except resolver.NXDOMAIN:
            pass


def main():
    infile = open("domainlist", "r")
    intext = infile.readlines()
    threads = []
    results = {}
    for address in [address.strip() for address in intext if address.strip()]:
        resolver_thread = Resolver(address, results)
        threads.append(resolver_thread)
        resolver_thread.start()

    for thread in threads:
        thread.join()

    outfile = open('final.csv', 'w')
    outfile.write("\n".join("%s,%s" % (address, ip) for address, ip in results.iteritems()))
    outfile.close()

if __name__ == '__main__':
    main()

如果这证明同时启动太多线程,您可以尝试分批执行,或使用队列(参见http://www.ibm.com/developerworks/aix/library/au-threadingpython/示例)

于 2010-06-22T11:43:55.617 回答
0

我会考虑使用纯 Python 库来执行 DNS 查询,而不是委托给dig,因为调用另一个进程可能相对耗时。(当然,在互联网上查找任何东西也相对耗时,所以 gilesc 所说的多线程仍然适用)谷歌搜索python dns将为您提供一些入门选择。

于 2010-06-22T01:41:22.877 回答
0

为了跟上服务器更新的步伐,执行时间必须少于 15 分钟。您的脚本需要 15 分钟才能运行吗?如果它不需要15分钟,你就完成了!

为了提高性能,我会调查之前运行的缓存和差异。

于 2010-06-22T03:34:21.380 回答