Python3多线程爬虫实例讲解代码


Posted in Python onJanuary 05, 2018

多线程概述

多线程使得程序内部可以分出多个线程来做多件事情,充分利用CPU空闲时间,提升处理效率。python提供了两个模块来实现多线程thread 和threading ,thread 有一些缺点,在threading 得到了弥补。并且在Python3中废弃了thread模块,保留了更强大的threading模块。

使用场景

在python的原始解释器CPython中存在着GIL(Global Interpreter Lock,全局解释器锁),因此在解释执行python代码时,会产生互斥锁来限制线程对共享资源的访问,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL。所以,虽然CPython的线程库直接封装了系统的原生线程,但CPython整体作为一个进程,同一时间只会有一个获得GIL的线程在跑,其他线程则处于等待状态。这就造成了即使在多核CPU中,多线程也只是做着分时切换而已。

如果你的程序是CPU密集型,多个线程的代码很有可能是线性执行的。所以这种情况下多线程是鸡肋,效率可能还不如单线程因为有上下文切换开销。但是如果你的代码是IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,多线程可以明显提高效率,例如多线程爬虫,多线程文件处理等等

多线程爬虫

多线程爬虫的代码实例

注: 以下代码在python3下运行通过, python2版本差异较大,不能运行成功,如需帮助请下方留意。

# coding=utf-8
import threading, queue, time, urllib
from urllib import request
baseUrl = 'http://www.pythontab.com/html/pythonjichu/'
urlQueue = queue.Queue()
for i in range(2, 10):
 url = baseUrl + str(i) + '.html'
 urlQueue.put(url)
 #print(url)
def fetchUrl(urlQueue):
 while True:
  try:
   #不阻塞的读取队列数据
   url = urlQueue.get_nowait()
   i = urlQueue.qsize()
  except Exception as e:
   break
  print ('Current Thread Name %s, Url: %s ' % (threading.currentThread().name, url))
  try:
   response = urllib.request.urlopen(url)
   responseCode = response.getcode()
  except Exception as e:
   continue
  if responseCode == 200:
   #抓取内容的数据处理可以放到这里
   #为了突出效果, 设置延时
   time.sleep(1)
if __name__ == '__main__':
 startTime = time.time()
 threads = []
 # 可以调节线程数, 进而控制抓取速度
 threadNum = 4
 for i in range(0, threadNum):
  t = threading.Thread(target=fetchUrl, args=(urlQueue,))
  threads.append(t)
 for t in threads:
  t.start()
 for t in threads:
  #多线程多join的情况下,依次执行各线程的join方法, 这样可以确保主线程最后退出, 且各个线程间没有阻塞
  t.join()
 endTime = time.time()
 print ('Done, Time cost: %s ' % (endTime - startTime))

运行结果:

1个线程时:

Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/2.html 
Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/3.html 
Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/4.html 
Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/5.html 
Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/6.html 
Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/7.html 
Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/8.html 
Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/9.html 
Done, Time cost: 8.182249069213867

2个线程时:

Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/2.html 
Current Thread Name Thread-2, Url: http://www.pythontab.com/html/pythonjichu/3.html 
Current Thread Name Thread-2, Url: http://www.pythontab.com/html/pythonjichu/4.html 
Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/5.html 
Current Thread Name Thread-2, Url: http://www.pythontab.com/html/pythonjichu/6.html 
Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/7.html 
Current Thread Name Thread-2, Url: http://www.pythontab.com/html/pythonjichu/8.html 
Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/9.html 
Done, Time cost: 4.0987958908081055

3个线程时:

Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/2.html 
Current Thread Name Thread-2, Url: http://www.pythontab.com/html/pythonjichu/3.html 
Current Thread Name Thread-3, Url: http://www.pythontab.com/html/pythonjichu/4.html 
Current Thread Name Thread-4, Url: http://www.pythontab.com/html/pythonjichu/5.html 
Current Thread Name Thread-2, Url: http://www.pythontab.com/html/pythonjichu/6.html 
Current Thread Name Thread-4, Url: http://www.pythontab.com/html/pythonjichu/7.html 
Current Thread Name Thread-1, Url: http://www.pythontab.com/html/pythonjichu/9.html 
Current Thread Name Thread-3, Url: http://www.pythontab.com/html/pythonjichu/8.html 
Done, Time cost: 2.287320137023926

通过调节线程数可以看到,执行时间会随着线程数的增加而缩短,抓取效率成正比增加。

总结:

Python多线程在IO密集型任务,多线程可以明显提高效率,CPU密集型任务不适合使用多线程处理。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 文件与目录操作
Dec 24 Python
python绘图库Matplotlib的安装
Jul 03 Python
Python比较文件夹比另一同名文件夹多出的文件并复制出来的方法
Mar 05 Python
Python中规范定义命名空间的一些建议
Jun 04 Python
浅谈用VSCode写python的正确姿势
Dec 16 Python
Python打开文件,将list、numpy数组内容写入txt文件中的方法
Oct 26 Python
python并发和异步编程实例
Nov 15 Python
Python之修改图片像素值的方法
Jul 03 Python
Python帮你微信头像任意添加装饰别再@微信官方了
Sep 25 Python
Mac中PyCharm配置Anaconda环境的方法
Mar 04 Python
Python基于wordcloud及jieba实现中国地图词云图
Jun 09 Python
Python作用域和名称空间的详细介绍
Apr 13 Python
python编写微信远程控制电脑的程序
Jan 05 #Python
使用python爬虫实现网络股票信息爬取的demo
Jan 05 #Python
简单实现python收发邮件功能
Jan 05 #Python
5款非常棒的Python工具
Jan 05 #Python
Python基于列表模拟堆栈和队列功能示例
Jan 05 #Python
Django 2.0版本的新特性抢先看!
Jan 05 #Python
微信跳一跳游戏python脚本
Apr 01 #Python
You might like
用PHP的ob_start();控制您的浏览器cache!
2007/02/14 PHP
php学习笔记之面向对象编程
2012/12/29 PHP
php中的常用魔术方法总结
2013/08/02 PHP
PHP中创建和验证哈希的简单方法实探
2015/07/06 PHP
php获得客户端浏览器名称及版本的方法(基于ECShop函数)
2015/12/23 PHP
PHP常用技巧汇总
2016/03/04 PHP
ThinkPHP5框架缓存查询操作分析
2018/05/30 PHP
js解析与序列化json数据(三)json的解析探讨
2013/02/01 Javascript
Jquery 类网页微信二维码图块滚动效果具体实现
2013/10/14 Javascript
Angularjs中的事件广播 —全面解析$broadcast,$emit,$on
2016/05/17 Javascript
详解AngularJS如何实现跨域请求
2016/08/22 Javascript
通过网页查看JS源码中汉字显示乱码的解决方法
2016/10/26 Javascript
JS判断数组那点事
2017/10/10 Javascript
React中的render何时执行过程
2018/04/13 Javascript
bootstrap实现点击删除按钮弹出确认框的实例代码
2018/08/16 Javascript
angularJs使用ng-repeat遍历后选中某一个的方法
2018/09/30 Javascript
js实现多个倒计时并行 js拼团倒计时
2019/02/25 Javascript
详解小程序开发经验:多页面数据同步
2019/05/18 Javascript
Vue 列表上下过渡效果的实例代码
2019/06/25 Javascript
Python使用修饰器执行函数的参数检查功能示例
2017/09/26 Python
python实现祝福弹窗效果
2019/04/07 Python
Pythony运维入门之Socket网络编程详解
2019/04/15 Python
Django框架之DRF 基于mixins来封装的视图详解
2019/07/23 Python
给Django Admin添加验证码和多次登录尝试限制的实现
2020/07/26 Python
浅谈python 类方法/静态方法
2020/09/18 Python
Python制作一个仿QQ办公版的图形登录界面
2020/09/22 Python
详解CSS3弹性伸缩盒
2020/09/21 HTML / CSS
ALDO英国官网:加拿大女鞋品牌
2018/02/19 全球购物
Oracle里面常用的数据字典有哪些
2014/02/14 面试题
信息专业本科生个人的自我评价
2013/10/28 职场文书
幼儿园新学期寄语
2014/01/18 职场文书
教师节促销活动方案
2014/02/14 职场文书
学期评语大全
2014/04/30 职场文书
2014年公务员转正工作总结
2014/11/07 职场文书
2014年检察院个人工作总结
2014/12/09 职场文书
Python常遇到的错误和异常
2021/11/02 Python