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的*args和**kwargs用法
Nov 01 Python
以Flask为例讲解Python的框架的使用方法
Apr 29 Python
在Python中操作字符串之replace()方法的使用
May 19 Python
Python实战小程序利用matplotlib模块画图代码分享
Dec 09 Python
python Web开发你要理解的WSGI & uwsgi详解
Aug 01 Python
python 字典操作提取key,value的方法
Jun 26 Python
Django框架模型简单介绍与使用分析
Jul 18 Python
解决Django加载静态资源失败的问题
Jul 28 Python
django框架面向对象ORM模型继承用法实例分析
Jul 29 Python
Python 获取命令行参数内容及参数个数的实例
Dec 20 Python
新年福利来一波之Python轻松集齐五福(demo)
Jan 20 Python
keras:model.compile损失函数的用法
Jul 01 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中调用JAVA
2006/10/09 PHP
可定制的PHP缩略图生成程式(需要GD库支持)
2007/03/06 PHP
处理单名多值表单的详解
2013/06/08 PHP
封装ThinkPHP的一个文件上传方法实例
2014/10/31 PHP
php实现的简单美国商品税计算函数
2015/07/13 PHP
PHP实现统计代码行数小工具
2019/09/19 PHP
解决jQuery插件tipswindown与hintbox冲突
2010/11/05 Javascript
IE与FireFox中的childNodes区别
2011/10/20 Javascript
JS获取网页属性包括宽、高等等
2014/04/03 Javascript
jQuery实现简单的文件上传进度条效果
2020/03/26 Javascript
jquery——九宫格大转盘抽奖实例
2017/01/16 Javascript
Vuex之理解state的用法实例
2017/04/19 Javascript
解决vue单页面应用中动态修改title问题
2019/06/09 Javascript
js设置鼠标悬停改变背景色实现详解
2019/06/26 Javascript
关于vue项目中搜索节流的实现代码
2019/09/17 Javascript
微信小程序实现页面浮动导航
2020/01/08 Javascript
jquery实现简单自动轮播图效果
2020/07/29 jQuery
Python入门篇之编程习惯与特点
2014/10/17 Python
在Python下利用OpenCV来旋转图像的教程
2015/04/16 Python
django加载本地html的方法
2018/05/27 Python
Python切片操作深入详解
2018/07/27 Python
手把手教你如何安装Pycharm(详细图文教程)
2018/11/28 Python
python读取并写入mat文件的方法
2019/07/12 Python
通过python改变图片特定区域的颜色详解
2019/07/15 Python
python join方法使用详解
2019/07/30 Python
python内存管理机制原理详解
2019/08/12 Python
Django基于客户端下载文件实现方法
2020/04/21 Python
HTML5拖放效果的实现代码
2016/11/17 HTML / CSS
REISS英国官网:伦敦High Street最受欢迎品牌
2016/12/21 全球购物
用C#语言写出与SQLSERVER访问时的具体过程
2013/04/16 面试题
大学生饮食配送创业计划书
2014/01/04 职场文书
如何写好升职自荐信
2014/01/06 职场文书
学习决心书
2014/03/11 职场文书
气象学专业个人求职信
2014/03/15 职场文书
优胜劣汰,强者为王——读《鲁滨逊漂流记》有感
2019/08/15 职场文书
CSS3常见动画的实现方式
2021/04/14 HTML / CSS