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异常学习笔记
Feb 03 Python
Python环境下搭建属于自己的pip源的教程
May 05 Python
Python实现的圆形绘制(画圆)示例
Jan 31 Python
Python实现二叉树前序、中序、后序及层次遍历示例代码
May 18 Python
Python3.7 新特性之dataclass装饰器
May 27 Python
TensorBoard 计算图的可视化实现
Feb 15 Python
使用TFRecord存取多个数据案例
Feb 17 Python
python轮询机制控制led实例
May 03 Python
scrapy处理python爬虫调度详解
Nov 23 Python
Python中lru_cache的使用和实现详解
Jan 25 Python
手把手教你配置JupyterLab 环境的实现
Feb 02 Python
浅谈Python xlwings 读取Excel文件的正确姿势
Feb 26 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
关于我转生变成史莱姆这档事:第二季PV上线,萌王2021年回归
2020/05/06 日漫
用PHP和ACCESS写聊天室(十)
2006/10/09 PHP
随时给自己贴的图片加文字的php水印
2007/03/16 PHP
php将会员数据导入到ucenter的代码
2010/07/18 PHP
php注销代码(session注销)
2012/05/31 PHP
php根据某字段对多维数组进行排序的方法
2015/03/07 PHP
php自定义函数实现JS的escape的方法示例
2016/07/07 PHP
PHP实现批量修改文件名的方法示例
2019/09/18 PHP
Google韩国首页图标动画效果
2007/08/26 Javascript
javascript中的作用域scope介绍
2010/12/28 Javascript
Javascript事件实例详解
2013/11/06 Javascript
将HTML格式的String转化为HTMLElement的实现方法
2014/08/07 Javascript
jquery+css实现动感的图片切换效果
2015/11/25 Javascript
javascript数组去重小结
2016/03/07 Javascript
Bootstrap的fileinput插件实现多文件上传的方法
2016/09/05 Javascript
原生JS:Date对象全面解析
2016/09/06 Javascript
浅谈键盘上回车按钮的js触发事件
2017/02/13 Javascript
Vue实现动态响应数据变化
2017/04/28 Javascript
axios拦截设置和错误处理方法
2018/03/05 Javascript
如何用JavaScript实现功能齐全的单链表详解
2019/02/11 Javascript
vue登录页实现使用cookie记住7天密码功能的方法
2021/02/18 Vue.js
[57:50]DOTA2上海特级锦标赛主赛事日 - 4 胜者组决赛Secret VS Liquid第二局
2016/03/05 DOTA
python基础教程之popen函数操作其它程序的输入和输出示例
2014/02/10 Python
Python实现HTTP协议下的文件下载方法总结
2016/04/20 Python
Python爬虫:将headers请求头字符串转为字典的方法
2019/08/21 Python
pandas数据拼接的实现示例
2020/04/16 Python
阿迪达斯丹麦官网:adidas丹麦
2016/10/01 全球购物
Tommy Hilfiger澳洲官网:美国高端休闲领导品牌
2020/12/16 全球购物
UNIX文件系统分类
2014/11/11 面试题
高校自主招生自荐信
2013/12/09 职场文书
驾驶员岗位职责
2014/01/29 职场文书
管理建议书范文
2014/05/13 职场文书
扶贫办主任查摆“四风”问题个人对照检查材料思想汇报
2014/10/02 职场文书
党员干部作风建设思想汇报范文
2014/10/25 职场文书
解除劳动关系协议书2篇
2014/11/28 职场文书
机关单位2016年法制宣传日活动总结
2016/04/01 职场文书