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使用mysqldb连接数据库操作方法示例详解
Dec 03 Python
Python urlopen()函数 示例分享
Jun 12 Python
对Python3中的input函数详解
Apr 22 Python
python 将md5转为16字节的方法
May 29 Python
解决Python获取字典dict中不存在的值时出错问题
Oct 17 Python
python读取各种文件数据方法解析
Dec 29 Python
python使用参数对嵌套字典进行取值的方法
Apr 26 Python
Python实现制度转换(货币,温度,长度)
Jul 14 Python
Python面向对象封装操作案例详解
Dec 31 Python
python根据字典的键来删除元素的方法
Aug 16 Python
python编写实现抽奖器
Sep 10 Python
python 实现弹球游戏的示例代码
Nov 17 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
解决phpmyadmin中文乱码问题。。。
2007/01/18 PHP
php截取中文字符串不乱码的方法
2013/12/25 PHP
windows服务器中检测PHP SSL是否开启以及开启SSL的方法
2014/04/25 PHP
PHP管理依赖(dependency)关系工具 Composer 安装与使用
2014/08/18 PHP
smarty自定义函数htmlcheckboxes用法实例
2015/01/22 PHP
详解thinkphp实现excel数据的导入导出(附完整案例)
2016/12/29 PHP
原生js拖拽(第一课 未兼容)拖拽思路
2013/03/29 Javascript
jQuery中setTimeout的几种使用方法小结
2013/04/07 Javascript
浅谈javascript 函数属性和方法
2015/01/21 Javascript
js获取域名的方法
2015/01/27 Javascript
jQuery实现的可编辑表格完整实例
2016/06/20 Javascript
微信小程序开发(二)图片上传+服务端接收详解
2017/01/11 Javascript
Vue.js 2.x之组件的定义和注册图文详解
2018/06/19 Javascript
angular将html代码输出为内容的实例
2018/09/30 Javascript
Vue.Draggable拖拽功能的配置使用方法
2020/07/29 Javascript
使用ESLint禁止项目导入特定模块的方法步骤
2019/03/04 Javascript
解决vue 表格table列求和的问题
2019/11/06 Javascript
jquery实现手风琴案例
2020/05/04 jQuery
忘记ftp密码使用python ftplib库暴力破解密码的方法示例
2014/01/22 Python
Python处理字符串之isspace()方法的使用
2015/05/19 Python
Python的dict字典结构操作方法学习笔记
2016/05/07 Python
python 递归遍历文件夹,并打印满足条件的文件路径实例
2017/08/30 Python
Python3.4学习笔记之常用操作符,条件分支和循环用法示例
2019/03/01 Python
对Python中 \r, \n, \r\n的彻底理解
2020/03/06 Python
python如何运行js语句
2020/09/09 Python
python中xlutils库用法浅析
2020/12/29 Python
预订从美国飞往印度的机票:MyTicketsToIndia
2017/05/19 全球购物
世界上最大的糖果店:Dylan’s Candy Bar
2017/11/07 全球购物
澳大利亚游乐场设备品牌:Lifespan Kids
2019/05/24 全球购物
最经典的大学生职业生涯规划范文
2014/03/05 职场文书
信息技术毕业生自荐信范文
2014/03/13 职场文书
大学学风建设方案
2014/05/04 职场文书
机电一体化专业求职信
2014/07/22 职场文书
学校教师师德师风承诺书
2015/04/28 职场文书
大学生读书笔记范文
2015/07/01 职场文书
Python-OpenCV教程之图像的位运算详解
2021/06/21 Python