- 创建一个 Queue.Queue() 的实例,然后使用数据对它进行填充。
- 将经过填充数据的实例传递给线程类,后者是通过继承 threading.Thread 的方式创建的。
- 生成守护线程池。
- 每次从队列中取出一个项目,并使用该线程中的数据和 run 方法以执行相应的工作。
- 在完成这项工作之后,使用 queue.task_done() 函数向任务已经完成的队列发送一个信号。
-
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
#!/usr/bin/env python#encoding:UTF-8importreimporturllibimportthreadingimporttimeimportQueuedefgetHtml(url):html_page=urllib.urlopen(url).read()returnhtml_page#提取网页中图片的URLdefgetUrl(html):pattern=r'http://.*?\.jpg!mid'#正则表达式 .*?(匹配http://和\.jpg!mid之间所有字符串)imgre=re.compile(pattern)imglist=re.findall(imgre,html)#re.findall(pattern,string) 在string中寻找所有匹配成功的字符串,以列表形式返回值returnimglistclassgetImg(threading.Thread):def__init__(self,queue):#进程间通过队列通信,所以每个进程需要用到同一个队列初始化threading.Thread.__init__(self)self.queue=queue#self.setDaemon(True) #守护线程self.start()#启动线程#使用队列实现进程间通信defrun(self):globalcountwhile(True):imgurl=self.queue.get()# print self.getName()#urllib.urlretrieve(url,filname) 将url的内容提取出来,并存入filename中urllib.urlretrieve(imgurl,'/home/dragonriver/图片/girls/%s.jpg'%count)# print "%s.jpg done"%countcount+=1ifself.queue.empty():breakself.queue.task_done()#当使用者线程调用 task_done() 以表示检索了该项目、并完成了所有的工作时,那么未完成的任务的总数就会减少。defmain():globalcounturl="http://girl-atlas.com/a/10130205170100000231"#要爬的网页地址html=getHtml(url)imglist=getUrl(html)threads=[]count=0queue=Queue.Queue()#将所有任务加入队列foriinrange(len(imglist)):queue.put(imglist[i])#多线程爬去图片foriinrange(4):thread=getImg(queue)threads.append(thread)#合并进程,当子进程结束时,主进程才可以执行#for thread in threads:# thread.join()#另一种保持主进程阻塞的方法,次方法和前面的self.queue.task_tone()相照应#两个要同时使用#queue.join()if__name__=='__main__':main()print"Down"
本文介绍如何利用Python的多线程技术高效地下载网页中的图片资源,通过创建线程池、使用队列实现任务分配与同步,最终实现图片的快速下载与保存。

被折叠的 条评论
为什么被折叠?



