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使用cPickle模块序列化实例
Sep 25 Python
Python中使用第三方库xlrd来写入Excel文件示例
Apr 05 Python
Python编程实现二叉树及七种遍历方法详解
Jun 02 Python
Python中表达式x += y和x = x+y 的区别详解
Jun 20 Python
Python 读取指定文件夹下的所有图像方法
Apr 27 Python
利用Python在一个文件的头部插入数据的实例
May 02 Python
Python 变量类型详解
Oct 10 Python
Python实现批量执行同目录下的py文件方法
Jan 11 Python
利用python实现对web服务器的目录探测的方法
Feb 26 Python
解决pyshp UnicodeDecodeError的问题
Dec 06 Python
window环境pip切换国内源(pip安装异常缓慢的问题)
Dec 31 Python
python manim实现排序算法动画示例
Aug 14 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
咖啡知识大全
2021/03/03 新手入门
substr()函数中文版
2006/10/09 PHP
探寻PHP脚本不报错的原因
2014/06/12 PHP
PHP编程中的__clone()方法使用详解
2015/11/27 PHP
PHP微信H5支付开发实例
2018/07/25 PHP
JavaScript的面向对象方法以及差别
2008/03/31 Javascript
node.js中的querystring.parse方法使用说明
2014/12/10 Javascript
jQuery制作效果超棒的手风琴折叠菜单
2015/04/03 Javascript
使用Bootstrap和Vue实现用户信息的编辑删除功能
2017/10/25 Javascript
JavaScript求一组数的最小公倍数和最大公约数常用算法详解【面向对象,回归迭代和循环】
2018/05/07 Javascript
微信小程序实现动态显示和隐藏某个控件功能示例
2018/12/14 Javascript
vue单页面在微信下只能分享落地页的解决方案
2019/04/15 Javascript
electron-vue利用webpack打包实现多页面的入口文件问题
2019/05/12 Javascript
echarts多条折线图动态分层的实现方法
2019/05/24 Javascript
vue实现一个矩形标记区域(rectangle marker)的方法
2020/10/28 Javascript
Python程序员鲜为人知但你应该知道的17个问题
2014/06/04 Python
pymongo给mongodb创建索引的简单实现方法
2015/05/06 Python
Python+matplotlib+numpy绘制精美的条形统计图
2018/01/02 Python
Python实现识别手写数字大纲
2018/01/29 Python
win10系统下Anaconda3安装配置方法图文教程
2018/09/19 Python
python利用多种方式来统计词频(单词个数)
2019/05/27 Python
如何运行.ipynb文件的图文讲解
2019/06/27 Python
idea2020手动安装python插件的实现方法
2020/07/17 Python
Python切片列表字符串如何实现切换
2020/08/06 Python
Python logging模块原理解析及应用
2020/08/13 Python
python用tkinter实现一个简易能进行随机点名的界面
2020/09/27 Python
Selenium 配置启动项参数的方法
2020/12/04 Python
关于HTML5的安全问题开发人员需要牢记的
2012/06/21 HTML / CSS
TripAdvisor德国:全球领先的旅游网站
2017/12/07 全球购物
AJAX应用和传统Web应用有什么不同
2013/08/24 面试题
北大青鸟学生求职信
2013/09/24 职场文书
应届生学校辅导员求职信
2013/11/07 职场文书
元旦晚会邀请函
2014/02/01 职场文书
yy婚礼司仪主持词
2014/03/14 职场文书
上市公司财务总监岗位职责
2015/04/03 职场文书
2015年高一班主任工作总结
2015/05/13 职场文书