使用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 ...
随机推荐
- Android服务之Service
android中服务是运行在后台的东西,级别与activity差不多.既然说service是运行在后台的服务,那么它就是不可见的,没有界面的东西.你可以启动一个服务Service来播放音乐,或者记录你 ...
- 抛弃EF,20分构建一个属于自己的ORM框架
Poiuyt_cyc 博客园首页新随笔联系订阅管理随笔 - 11 文章 - 0 评论 - 111 抛弃EF,20分构建一个属于自己的ORM框架 相信EF大家都不陌生了,因为数据库表跟程序实体是一一 ...
- C#隐式运行CMD命令(隐藏命令窗口)
原文 C#隐式运行CMD命令(隐藏命令窗口) 本文实现了C#隐式运行CMD命令的功能.下图是实例程序的主画面.在命令文本框输入DOS命令,点击"Run"按钮,在下面的文本框中输出运 ...
- Solution multisite htaccess cleanURL
My solution to getting Clean URL working with my multisite setup drupal 4.7 I added Alias to my http ...
- C#语言基础02
字符串:string s="ab";string s1="a\nb";//n:newline或者next的意思. string s="a\\b&quo ...
- Oracle 学习用
最近在学习Oracle数据库 ,公司用这个,学习到现在,唉!苦逼的程序员呀! 也只能在这里发发牢骚了,这个是转载的 ,发完睡觉! oracle sql语句 一.ORACLE的启动和关闭 .在单机环境下 ...
- 数往知来 CSS<十二>
div+css基础 一.外部样式<!--外部样式可以使网页与样式分离,分工处理 1.写网页,主要提供内容,一般都会有固定的结构,具有id等属性的标签包括特定的内容 2.根据结构写样式另存为css ...
- DOS 命令大全
MS DOS 命令大全 一.基础命令 1 dir 无参数:查看当前所在目录的文件和文件夹. /s:查看当前目录已经其所有子目录的文件和文件夹. /a:查看包括隐含文件的所有文件. /ah:只显示出隐含 ...
- [转] Python自动单元测试框架
一.软件测试 大型软件系统的开发是一个很复杂的过程,其中因为人的因素而所产生的错误非常多,因此软件在开发过程必须要有相应的质量保证活动,而软件测试则是保证质量的关键措施.正像软件熵(software ...
- mysql 管理、备份、还原及查询的图形化gui工具
mysql-workbench sudo apt-get install mysql-workbench