繁体   English   中英

在python脚本中增加吞吐量

[英]Increasing throughput in a python script

我正在通过挖掘处理DNSBL中成千上万个域名的列表,创建URL和IP的CSV。 这是一个非常耗时的过程,可能需要几个小时。 我的服务器的DNSBL每15分钟更新一次。 有什么办法可以增加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

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

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

好吧,可能是名称解析让您花了很长时间。 如果您将其排除在外(即,如果以某种方式快速返回的话),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/) 。 )

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

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

我将研究以前运行的缓存和差异,以提高性能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM