Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
提高python脚本的吞吐量_Python_Unix_Python Multithreading - Fatal编程技术网

提高python脚本的吞吐量

提高python脚本的吞吐量,python,unix,python-multithreading,Python,Unix,Python Multithreading,我正在处理从DNSBL到dig的数千个域名列表,创建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('

我正在处理从DNSBL到dig的数千个域名列表,创建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

这里的绝大多数时间都花在了对
dig
的外部调用上,因此要提高速度,需要使用多线程。这将允许您同时运行对
dig
的多个调用。请参见示例:。或者,可以使用Twisted()


编辑:你是对的,这是不必要的。

< P>我会考虑使用纯Python库来做DNS查询,而不是委托给代码> DIG/<代码>,因为调用另一个过程可能是比较耗时的。(当然,在互联网上查找任何东西也相对耗时,因此gilesc关于多线程的说法仍然适用)谷歌搜索python dns将为您提供一些开始的选项。

为了跟上服务器更新的步伐,必须在15分钟内执行。您的脚本运行需要15分钟吗?如果不花15分钟,你就完了


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

嗯,可能是名称解析花了您这么长时间。如果算出来(即,如果dig以某种方式非常快地返回),Python应该能够轻松地处理数千个条目

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

因此,请使用以下设备安装:

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()

如果这证明同时启动了太多线程,您可以尝试成批执行,或者使用队列(请参见示例)

显示脚本或脚本的伪代码。这样我们可以提出改进建议。15分钟内的数千个列表应该很容易在python的限制范围内。+1,请向我们展示您所拥有的。顺便说一句,如果我理解正确的话,很可能是名称解析,而不是脚本本身,花费了这么长时间。如果是这种情况,您可能希望尝试线程化解决方案。不管实际解决方案如何,以下几点提示:避免为不同的事情重用同一变量(text=open…;text=text.read());使用“text.splitlines()”而不是正则表达式;避免使用“file”作为变量名,因为它在Python2.x中是一个关键字(尽管在Python3中不是);请记住关闭您的文件句柄(即使在本例中Python将为您完成此操作)。+1用于说明需要执行线程调用来挖掘。你应该在回答中把这一点放在首位。与执行DNS查询所花费的时间相比,启动新进程的开销可以忽略不计,但gilesc的回答已经涵盖了网络延迟。效果很好,但我不断收到这些错误:File“/home/okim/dnspython/DNS/resolver.py”,第541行,在_compute_timeout raise timeout有什么想法吗?显然,您的名称服务器无法在默认超时内解析某些名称(可能是权威名称服务器没有响应)。如果您想跳过这些,只需将“except resolver.NXDOMAIN:”行更改为“except(resolver.NXDOMAIN,resolver.Timeout):”。如果您想以不同的方式处理这些异常,只需在NXDOMAIN子句之后添加一个新的except子句。顺便说一句,NXDOMAIN捕获不存在的域。顺便说一句,如果您发现问题出在您的名称服务器上,您可以使用“resolver.default_resolver.nameservers.insert(0,'8.8.8')”名义上指定一个。但我只是为了完整起见,更可能的是,在数千个域名中,其中一些根本没有响应(特别是因为你提到它们来自黑名单)。是的,我的域名服务器有问题。不过,更改“除外”也行。谢谢你的帮助!