前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python-并发下载-queue模块

Python-并发下载-queue模块

作者头像
小团子
发布2019-07-18 15:18:45
1.3K0
发布2019-07-18 15:18:45
举报
文章被收录于专栏:数据云团数据云团数据云团
import queue

由于外部网络不稳定,在使用单线程爬取网页数据时,如果有一个网页响应速度慢或者卡住,整个程序都要等待下去。因此,可以使用多线程、多进程、协程技术实现并发下载网页。

  • 并发篇-python多线程
  • 并发篇-python协程
  • 并发篇-python多进程

多进程适用于 CPU 密集型的代码,例如各种循环处理、大量的密集并行计算;

多线程适用于 I/O 密集型的代码,例如文件处理、网络交互;

协程无须通过操作系统调度,没有进程、线程之间的切换和创建等开销,适用于大量不需要 CPU 的操作,例如网络 I/O 等。

实际上,限制爬虫程序发展的瓶颈就在于网络 I/O,原因是网络 I/O 的速度赶不上 CPU 的处理速度。

一、多线程爬虫流程分析

多线程爬虫将多线程技术运用在采集网页信息和解析网页内容上。

① 准备一个网址列表,爬取数据的网页列表。

与单线程爬虫不同,多线程爬虫可以同时爬取多个网页。

② 同时开启多个线程爬取网页内容。

一般启动固定数量的线程,一个线程爬取完一个网页之后,接着爬取下一个。线程的数量不宜过多,否则,线程调度的时间太长,效率低;线程的数量也不宜过少,否则不能最大限度地提高爬取速度。

③ 将爬取到的网页源代码存储在一个列表中。

④ 同时使用多个线程对网页源代码表的网页内容进行解析。

⑤ 将解析之后的数据存储起来。

二、使用 queue 模块实现多线程爬虫

多线程爬虫要在内存中存储数据,包括待爬取的网页列表、爬取到的数据等,一般要使用到 queue 模块。

queue 模块是 Python 内置的标准模块,可以直接通过引用。

import queue

在 queue 模块中提供了 3种同步的、线程安全的队列,分别由 3个类 Queue、LifoQueue 和 PriorityQueue,它们的唯一区别是元素取出的顺序不同。并且,LifoQueue 和 PriorityQueue 都是 Queue 的子类。

① Queue(FIFO队列)

Queue 类表示一个基本的 先进先出 队列,创建方法是 Queue.Queue(maxsize=0),其中 maxsize 是个整数,指明了队列中能存放的数据个数的上限。

from queue import Queue

# 将四个数字放在了 Queue 队列中,然后依次取出它的元素值
queue_object = Queue()
for i in range(4):
  queue_object.put(i)
while not queue_object.empty():
  print(queue_object.get())

② LifoQueue(LIFO队列)

LifoQueue 类表示 后进先出 队列,与栈类似,都是后进入的元素先出来。使用 Queue.LifoQueue(maxsize=0),其中 maxsize 是个整数,指明了队列中能存放的数据个数的上限。

from queue import LifoQueue

# 将四个数字放在了 LifoQueue 队列中,取出的元素的顺序与 Queue 相反,最后放入的元素最先被取出。
lifo_queue = LifoQueue()
for i in range(4):
  lifo_queue.put(i)
while not lifo_queue.empty():
  print(lifo_queue.get())

③ PriorityQueue(优先级队列)

PriorityQueue 类表示 优先级 队列,按级别顺序取出元素,级别最低的最先取出。优先级队列中的元素一般采用元组(优先级别,数据)的形式来存储。Queue.PriorityQueue(maxsize=0)。

将任务 Job 存入 PriorityQueue 中,每个 Job 都有一个优先级 level,level 值越低,则代表的优先级越高。在调用 get() 方法时,按照优先级从高到低的顺序从队列中取出元素。

from queue import PriorityQueue

class Job(object):
  def __init__(self, level, description):
    self.level = level
    self.description = description
    return
    
  def __lt__(self, other):
    return self.level < other.level

priority_queue = PriorityQueue()
priority_queue.put(Job(5, "中级别工作"))
priority_queue.put(Job(10, "低级别工作"))
priority_queue.put(Job(1, "重要工作"))

while not priority_queue.empty():
  next_job = priority_queue.get()
  print("开始工作:", next_job.description)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据云团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
GPU 云服务器
GPU 云服务器(Cloud GPU Service,GPU)是提供 GPU 算力的弹性计算服务,具有超强的并行计算能力,作为 IaaS 层的尖兵利器,服务于深度学习训练、科学计算、图形图像处理、视频编解码等场景。腾讯云随时提供触手可得的算力,有效缓解您的计算压力,提升业务效率与竞争力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档