爬虫中多线程的运用

检索百张的页面,爬虫运行下来往往在一小时以内,时间上还是可以接受的。但当整理后的URL数量过多的时候,就只能考虑采取多线程分步爬取了。Python里控制多线程只需要用到模板threading,而且只需要用到其中的Thread。

简单的使用方法如下:

 1 import time
 2 import threading
 3 
 4 def spider(number):
 5     print u"%d 号爬虫开始运行! 时间: %s" % (number,time.strftime('%H:%M:%S',time.localtime()))
 6     time.sleep(2)
 7     print u"%d 号爬虫运行结束! 时间: %s" % (number,time.strftime('%H:%M:%S',time.localtime()))
 8     
 9 if __name__ == "__main__":
10     thread = 5
11     print u"主程序开始运行! 时间: %s" % time.strftime('%H:%M:%S',time.localtime())
12     for i in range(1,thread+1):
13         t = threading.Thread(target=spider,args=(i,))
14         t.start()
15     
16     print u"主程序运行结束! 时间: %s" % time.strftime('%H:%M:%S',time.localtime())
Thread使用方法为:
threading.Thread(target=线程运行的函数,args=(参数)) 其中参数用逗号分隔,并以逗号结尾。
随后使用start启动。
运行结果如下:

可以看到五个线程同步运行,因sleep设置的时间相同,所以也同步结束。

但有一个缺点是第16行代码在五个线程启动后随即也就运行了,相当于此时主线程已经结束了而那五个子线程还在运行。

控制策略有两个

在start之前把子线程设置为守护线程

修改代码如下:

1 for i in range(1,thread+1):
2   t = threading.Thread(target=spider,args=(i,))
3   t.setDaemon(True)
4   t.start()

运行结果如下:

子线程在主线程结束的时候也同步结束,未运行的部分也就不再运行了。

在主线程中使用join,让主线程挂起等待子线程结束

修改代码如下:

1 for i in range(1,thread+1):
2     t = threading.Thread(target=spider,args=(i,))
3     t.start()
4 t.join()

从运行结果可以看到主线程停留在t.join()的位置,一直等到五个子线程全部结束后才开始继续向后运行。

以上就是需要用到的threading模板里所有的东西了。

在整理好需要处理的数据列表后,我们只需要将列表分段分别交给不同的线程来处理,主线程等待所有数据处理完毕之后再进行下一步操作,如下:

 1 import time
 2 import threading
 3 
 4 def spider(number,data_list):
 5     print u"%d 号爬虫开始运行! 时间: %s" % (number,time.strftime('%H:%M:%S',time.localtime()))
 6     print u"%d 号爬虫需要处理的数据有%s ! 时间: %s" % (number,str(data_list),time.strftime('%H:%M:%S',time.localtime()))
 7     time.sleep(2)
 8     print u"%d 号爬虫运行结束! 时间: %s" % (number,time.strftime('%H:%M:%S',time.localtime()))
 9     
10 if __name__ == "__main__":
11     thread = 5
12     ls = []
13     ls2 = []
14     for n in range(1,58):
15         ls.append(n)
16     length = len(ls)//thread+1
17     for m in range(thread):
18         ls2.append(ls[length*m:length*m+length])
19         
20     print u"主程序开始运行! 时间: %s" % time.strftime('%H:%M:%S',time.localtime())
21     for i in range(1,thread+1):
22         t = threading.Thread(target=spider,args=(i,ls2[i-1],))
23         t.start()
24     t.join()
25     print u"主程序运行结束! 时间: %s" % time.strftime('%H:%M:%S',time.localtime())

运行结果如下:

五个线程分步处理各自被分配到的数据,总体运行时间大幅缩减。当然机器给力的话,可以增加线程数,得到更快的速度。

 

 

 

 
posted @ 2018-04-11 20:43  Geek_Arking  阅读(3320)  评论(0编辑  收藏  举报