使用Python脚本进行域名解析
因为在研究爬虫,所以也了解了下域名解析。要提高爬虫的效率,就需要提高域名解析的效率。我将爬虫记录下的域名作为待解析的域名来测试各域名解析方法的效率。我尝试以下四种方法:1. 单线程依次解析各域名,2. 多线程同时解析各域名,3. 线程池解析各域名,4. 使用adns库解析各域名。其中,第四种方法最高效也最安全,推荐大家使用。完整的代码请见:https://github.com/sunada/dnsResolve
1. 单线程依次解析域名
这种方法最直观。使用一个循环,依次使用socket.getaddrinfo('host',None)来进行解析。这种方法很低效:解析100个域名花费了392s,解析500个域名花费了1695s。这是由于getaddrinfo方法解析单个域名就比较费时间,使用单线程阻碍的方法来解析500个域名,自然会耗时较长。
import time
import socket def ReadHost(file):
hosts=[]
...
return hosts def SynResolve(fr):
hosts=ReadHost(fr)
IPs={}
for host in hosts:
try:
results=socket.getaddrinfo(host,None)
for result in results:
print host, result[4][0]
IPs[result[4][0]]=host
except Exception,e:
print e
file.close() if __name__=='__main__':
start=time.time()
print 'starting at: ',start
SynResolve('host')
print 'ending at: ',time.time()-start
2. 多线程解析域名
这种方法也好理解。每解析一个域名时,就建立一个新的线程,用这个线程去解析此域名。这种方法较为高效,但在线程数量太大时错误率较高。解析500个域名需要创建500个线程,试验结果表示:执行程序时给出了“thread.error: can't start new thread的提示。可能受此影响,运行脚本时提示个别域名无法解析。对这些域名单独使用socket.getaddrinfo进行解析时,都可解析成功;如果只需解析100个线程,则不会提示thread.error的提示,仅有一个域名提示无法解析成功。使用此方法,解析100个域名大约耗时1分钟左右。因为我运行脚本的机器所在的网速不太稳定,所以
也许这种方法所需要的时间更短。
代码主要分为两个部分:一部分为一个继承自threading.Thread的子类,并通过run()函数这一成员函数来实现每个线程所要完成的工作;另一部分为一个函数,负责将需要完成的任务分配给一个新创建的线程。由于需要将解析得到的域名和对应的IP保存下载,所以需要各线程共同修改IPhost这一字典。代码中使用了一个锁(mutex),只有得到锁的线程才能向IPhost写入,否则只能等待。这样可保证IPhost中IP与域名信息正确的对应关系。否则在线程的来回快速切换中,可能造成这种对应关系记录的不准确。
import time
import socket def ReadHost(file):
hosts=[]
...
return hosts class ThreadClass(threading.Thread):
def __init__(self,host):
self.host=host
threading.Thread.__init__(self) def run(self):
global IPhost
try:
res=socket.getaddrinfo(self.host,None)
if mutex.acquire(1):
for re in res:
IPhost[re[4][0]]=self.host
mutex.release()
except Exception, e:
print self.host, e def MulThreadResolve(fr):
start=time.ctime()
print 'starting MulThreadResolve at: ',start
hosts=ReadHost(fr)
threads=[]
for host in hosts:
t=ThreadClass(host)
threads.append(t) cntHost=len(hosts)
for i in range(cntHost):
threads[i].start() for i in range(cntHost):
threads[i].join() print 'ending MulThreadResolve at :', time.ctime() if __name__='__main__':
IPhost={}
mutex=threading.Lock()
MulThreadResolve('host1')
print IPhost
3. 利用线程池进行域名解析
通过方法2,我们知道在一个进程中创建过多的线程来执行任务,是危险的。自然的,我们就会想到利用有限个线程来进行域名解析。比如,用100个线程去解析500域名。当一个线程解析完成后,无需关闭,继续从队列中取出一个域名进行解析。如此反复,直到队列中为空,所有域名都得到解析为止。使用线程池的另一个好处是省略了新建线程和关闭线程的时间;如果线程执行的任务耗时较短,那么通过线程池节省下来的这笔时间将会是可观的。可以预计,此法将比方法2耗时更多。
利用线程池进行域名解析的代码较方法2要复杂一些,但也不难理解。代码仍旧主要分为两个部分:一部分为一个继承自threading.Thread的子类,并通过run()函数这一成员函数来实现每个线程所要完成的工作。run()函数中,当一个线程空闲时,就去队列中取出一个域名;直到队列为空,函数的任务也就完成了。另一部分为一个类,负责将任务分配给一个新创建的线程,并检查交由run()完成的任务是否都已完成。由于需要进行的管理行为较方法2更多,所以将这些管理行为整合在一起,弄成了一个类。因为一个线程需要进行多次域名解析工作,所以需要将这些待解析的域名进行排队。队伍的容量是有限的,只有当队未满时才能将域名加入队列等待线程将其取走并进行解析。由于代码较长,我就把它放在这里了。
使用Python脚本进行域名解析的更多相关文章
- freeswitch嵌入python脚本
操作系统:debian8.5_x64 freeswitch 版本 : 1.6.8 python版本:2.7.9 开启python模块 安装python lib库 apt-get install pyt ...
- python脚本后台运行
问题描述: 环境: CentOS6.4 一个用python写的监控脚本test1.py,用while True方式一直运行,在ssh远程(使用putty终端)时通过以下命令启动脚本: python t ...
- 某互联网后台自动化组合测试框架RF+Sikuli+Python脚本
某互联网后台自动化组合测试框架RF+Sikuli+Python脚本 http://www.jianshu.com/p/b3e204c8651a 字数949 阅读323 评论1 喜欢0 一.**Robo ...
- 动态执行python脚本
前言 存在许多独立的python脚本,这些脚本可能会增加,也可能会减少,现在需要按照某种顺序调度这些程序.在python的standard library中,有一个模块imp可以实现动态的调用ptho ...
- 一个获取指定目录下一定格式的文件名称和文件修改时间并保存为文件的python脚本
摘自:http://blog.csdn.net/forandever/article/details/5711319 一个获取指定目录下一定格式的文件名称和文件修改时间并保存为文件的python脚本 ...
- SecureCRT中python脚本编写
SecureCRT中python脚本编写学习指南 SecureCRT python 引言 在测试网络设备中,通常使用脚本对设备端进行配置和测试以及维护:对于PE设备的测试维护人员来说使用较多是Secu ...
- Python脚本配合Linux计划任务工作
经常遇到直接运行Python脚本没有问题,但是一放入/etc/crontab之后就歇菜的情况,总结了一下,大致需要注意以下几点: 1. 脚本首行加入#!/usr/bin/env python 2. 脚 ...
- Labview调用Python脚本
Labview程序框图如下: Python脚本如下: #!/usr/bin/env pythonimport sys #Command Line Arguements are stored in li ...
- 使用Runtime.getRuntime().exec()在java中调用python脚本
举例有一个Python脚本叫test.py,现在想要在Java里调用这个脚本.假定这个test.py里面使用了拓展的包,使得pythoninterpreter之类内嵌的编译器无法使用,那么只能采用ja ...
随机推荐
- Asp.net 访问数据库的几种方式
ASP.NET中连接数据库的各种方法 连接SQL数据库的方法:(一).在Web.Config中创建连接字符串:1.<add name="ConnectionString" c ...
- 如何查看python selenium的api
1. 打开命令行: command+R2. 输入: python -m pydoc -p 4567,然后:Enter3. 然后在浏览器中访问http://localhost:45674. 按ctrl+ ...
- Lucene 入门需要了解的东西
全文搜索引擎的原理网上大段的内容,要想深入的学习,最好的办法就是先用一下,lucene 发展比较快,下面是写第一个demo 要注意的一些事情: 1.Lucene的核心jar包,下面几个包分别位于不同 ...
- gcc命令行详解
介绍] ----------------------------------------- 常见用法: GCC 选项 GCC 有超过100个的编译选项可用. 这些选项中的许多你可能永远都不会用到, 但 ...
- jetty8的多实例部署(LT项目开发参考)
LT项目使用的EIP是运行在JETTY上,此文供开发和实施参考 1.windows下 win下部署多个jetty8很简单,首先将jetty8复制多个文件夹,其次按分配的端口号修改[JETTY_HOME ...
- QCon2013上海站总结 -- 整体印象和感悟
基本情况: QCon 2013(http://www.qconshanghai.com/)上海站的活动一共为期3天(周五.六和日).活动在上海的光大会展中心举行的. QCon(全球软件开发者大会)是由 ...
- 一起学习 微服务(MicroServices)-笔记
笔记 微服务特性: 1. 小 专注与做一件事(适合团队就是最好的) 2. 松耦合 独立部署 3. 进程独立 4. 轻量级通信机制 实践: 1. 微服务周边的一系列基础建设 Load Balancing ...
- 轻松学习Linux之理解Shell的硬链接与软连接
大家在学习linux的过程中常常遇到一些模糊且容易混淆的概念比如什么是硬链接和软链接,他们有什么区别? 软连接有点象windows中的快捷方式,连接和目标文件具有相同的节点,而硬连接就好象重新复制 ...
- Pylint
[Pylint] pylint的调用命令: pylint [options] module_or_package 使用 Pylint 对一个模块 module.py 进行代码检查: 1. 进入这个模块 ...
- C++11用于元编程的类别属性
[C++11用于元编程的类别属性] 许多算法能作用在不同的数据类别; C++ 模板支持泛型,这使得代码能更紧凑和有用.然而,算法经常会需要目前作用的数据类别的信息.这种信息可以通过类别属性 (type ...