这一章,咱们先引入几个关键概念,为下一章的多线程爬虫实战做好铺垫。
一、Queue线程
在线程中,访问⼀些全局变量,加锁是⼀个经常的过程。如果你想把⼀些数据存储到某个队列中,那么Python内置了⼀个线程安全的模块叫做queue模块。Python中的queue模块中提供了同步的、线程安全的队列类,包括 FIFO(先进先出)队列Queue,LIFO(后⼊先出)队列LifoQueue。这些队列,都实现了锁原语(可以理解为原⼦操作,即要么不做,要么都做完),能够在多线程中直接使⽤。可以使用队列来实现线程间的同步。
下面简单讲讲队列线程的使用:
先导入模块:
from queue import Queue
实际运用一下队列:
# 创建一个大小为3的队列
# 通过 Queue(maxsize) 来实现:初始化,创建一个先进先出的队列。
q = Queue(3)
# qsize():返回队列的大小。
# empty():判断队列是否为空。
# True表示空的队列,False 队列不是空的
print(q.empty()) # 此处为True
# full():判断队列是否满了。
# False队列不是满的,True队列是满的
print(q.full()) # 此处为False
以上为队列为空的情况,这次加上数据:
# 放入1,2,3,共三个数
q.put(1)
q.put(2)
q.put(3)
print(q.empty()) # 此处结果为False
print(q.full()) # 此处结果为True
# get():从队列中取最后一个数据。
# put():将一个数据放到队列中。
二、生产者和消费者
生产者和消费者模式是多线程开发中常见的⼀种模式。通过生产者和消费者模式,可以让代码达到高内聚低耦合的目标,线程管理更加方便,程序分工更加明确。 生产者的线程专门用来生产⼀些数据,然后存放到容器中(中间变量)。消费者在 从这个中间的容器中取出数据进行消费。
这是生产者与消费者的流程图:
下面我们通过代码来简单实现生产者与消费者的关系:
先导入模块:
import threading
import random
import time
定义两个类,一个是生产者(不断挣钱),一个是消费者(不断花钱):
# 定义变量gMoney
gMoney = 0
# 定义一个变量 保存生成的次数 默认是0次
gTimes = 0
# 定义一把锁
gLock = threading.Lock()
# 定义生产者
class Producer(threading.Thread):
def run(self) -> None:
global gMoney
global gTimes
while True:
gLock.acquire() # 上锁
if gTimes >= 10:
gLock.release()
break
# 随机挣钱
money = random.randint(0,100) # 0 <= money <= 100
gMoney += money
gTimes += 1
print('%s生成了%d元钱' % (threading.current_thread().name, money))
gLock.release() # 解锁
time.sleep(1)
# 定义消费者
class Consumer(threading.Thread):
def run(self) -> None:
global gMoney
while True:
gLock.acquire() # 上锁
# 随机花钱
money = random.randint(0, 100) # 0 <= money <= 100
# 注意,这里要做一个判断,不能挣钱低于花钱
if gMoney >= money:
gMoney -= money
print('%s消费了%d元钱'%(threading.current_thread().name,money))
else:
if gTimes >= 10:
gLock.release()
break
print('%s消费了%d元钱,但是余额只有%d'%(threading.current_thread().name,money,gMoney))
gLock.release() # 解锁
time.sleep(1)
最后定义主线程并执行:
def main():
# 开启5个生产者
for i in range(5):
th = Producer(name='生产者%d号'%i)
th.start()
# 开启5个消费者
for i in range(5):
th = Consumer(name='消费者%d号' % i)
th.start()
if __name__ == '__main__':
main()
结果如下:
到这里,我们已经简单实现多任务线程,下一章将会讨论多任务线程爬虫的实战操作。
实战部分:
第一篇:Python爬虫实战之 爬取全国理工类大学数量+数据可视化
爬虫基础部分:
第一篇:Python的要点(搭建环境、安装配置、第三方库导入方法详细过程)
第二篇:Python爬虫初探(一)——了解爬虫
第三篇:Python爬虫初探(二)——爬虫的请求模块
第四篇:Python爬虫初探(三)——爬虫之正则表达式介绍
第五篇:Python爬虫初探(四)——爬虫之正则表达式实战(爬取图片)
第六篇:Python爬虫初探(五)——爬虫之xpath与lxml库的使用
第七篇:Python爬虫初探(六)——爬虫之xpath实战(爬取高考分数线信息)
第八篇:Python爬虫初探(七)——爬虫之Beautifulsoup4介绍(Ⅰ)
第九篇:Python爬虫初探(八)——爬虫之Beautifulsoup4介绍(Ⅱ)
第十篇:Python爬虫初探(九)——爬虫之Beautifulsoup4实战(爬取豆瓣信息)
第十一篇:Python爬虫初探(十)——爬虫总结
爬虫进阶部分:
第一篇:Python爬虫进阶(一)——爬虫之动态数据与selenium
第二篇:Python爬虫进阶(二)——爬虫之多任务模块(Ⅰ)
第三篇:Python爬虫进阶(三)——爬虫之多任务模块(Ⅱ)