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备份Mysql脚本
Aug 11 Python
Python之eval()函数危险性浅析
Jul 03 Python
Python遍历zip文件输出名称时出现乱码问题的解决方法
Apr 08 Python
Python入门_浅谈数据结构的4种基本类型
May 16 Python
Python实现监控键盘鼠标操作示例【基于pyHook与pythoncom模块】
Sep 04 Python
python实现kmp算法的实例代码
Apr 03 Python
树莓派实现移动拍照
Jun 22 Python
python实现的发邮件功能示例
Sep 11 Python
Python实现敏感词过滤的4种方法
Sep 12 Python
python中绕过反爬虫的方法总结
Nov 25 Python
python 实现简易的记事本
Nov 30 Python
基于python实现银行管理系统
Apr 20 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标签云的实现代码
2012/10/10 PHP
php 目录遍历、删除 函数的使用介绍
2013/04/28 PHP
php操作xml入门之xml标签的属性分析
2015/01/23 PHP
php session的应用详细介绍
2017/03/22 PHP
Javascript this关键字使用分析
2008/10/21 Javascript
JavaScript中setInterval的用法总结
2013/11/20 Javascript
JQuery的$命名冲突详细解析
2013/12/28 Javascript
JavaScript每天定时更换皮肤样式的方法
2015/07/01 Javascript
理解JavaScript中worker事件api
2015/12/25 Javascript
jquery插件uploadify多图上传功能实现代码
2016/08/12 Javascript
JavaScript数组迭代方法
2017/03/03 Javascript
vue中如何创建多个ueditor实例教程
2017/11/14 Javascript
vue-cli构建项目下使用微信分享功能
2018/05/28 Javascript
NodeJS使用Range请求实现下载功能的方法示例
2018/10/12 NodeJs
vue动态加载SVG文件并修改节点数据的操作代码
2020/08/17 Javascript
[01:29:42]Liquid vs VP Supermajor决赛 BO 第一场 6.10
2018/07/05 DOTA
pyv8学习python和javascript变量进行交互
2013/12/04 Python
详解Python中映射类型的内建函数和工厂函数
2015/08/19 Python
Python使用ntplib库同步校准当地时间的方法
2016/07/02 Python
python利用matplotlib库绘制饼图的方法示例
2016/12/18 Python
Python中super函数的用法
2017/11/17 Python
python实现祝福弹窗效果
2019/04/07 Python
Python多线程threading模块用法实例分析
2019/05/22 Python
python调试神器PySnooper的使用
2019/07/03 Python
Python面向对象编程基础实例分析
2020/01/17 Python
在python中修改.properties文件的操作
2020/04/08 Python
用 Django 开发一个 Python Web API的方法步骤
2020/12/03 Python
英国床和浴室商场:Bed & Bath Emporium
2018/05/20 全球购物
澳大利亚二手奢侈品网站:Modsie
2019/09/23 全球购物
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
开展党的群众路线教育实践活动方案
2014/02/05 职场文书
市场营销专业毕业生求职信
2014/07/21 职场文书
意向书范本
2014/07/29 职场文书
2014年护士个人工作总结
2014/11/11 职场文书
导游词之杭州西湖
2019/09/19 职场文书
解决pycharm下载库时出现Failed to install package的问题
2021/09/04 Python