我正在通过挖掘处理来自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
答案 0 :(得分:2)
这里的绝大部分时间用于dig
的外部调用,因此为了提高速度,您需要多线程。这样您就可以同时对dig
进行多次调用。例如,请参阅:Python Subprocess.Popen from a thread。或者,您可以使用Twisted(http://twistedmatrix.com/trac/)。
编辑:你是对的,其中大部分是不必要的。
答案 1 :(得分:2)
嗯,这可能是你花了这么长时间的名字解析。如果算上这一点(即,如果以某种方式很快地挖掘),Python应该能够轻松处理数千个条目。
那就是说,你应该尝试一种线程方法。这将(理论上)同时解决几个地址,而不是顺序解决。你也可以继续使用dig来解决这个问题,下面修改我的示例代码应该是微不足道的,但是,为了使事情变得有趣(并且希望更加pythonic),让我们使用现有模块:{{3 }}
所以,请安装:
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()
如果证明同时启动太多线程,您可以尝试批量执行或使用队列(请参阅dnspython示例)
答案 2 :(得分:0)
我考虑使用纯Python库来执行DNS查询,而不是委托给dig
,因为调用另一个进程可能相对耗时。 (当然,在互联网上查找任何内容也相对耗时,因此gilesc所说的多线程仍然适用)Google搜索 python dns 将为您提供一些入门选项。< / p>
答案 3 :(得分:0)
为了跟上服务器更新的步伐,必须花费不到15分钟的时间来执行。你的脚本需要15分钟才能运行吗?如果不花15分钟,你就完成了!
我会调查之前运行的缓存和差异,以提高性能。