背景
在使用爬虫程序下载资源时,经常由于资源过大,下载时间太长,程序长时间处于下载中,我们能看到的控制台一直处于夯住的状态, 无法知道此时的下载情况和程序运行状态,就算此时程序运行出错我们也无法知道, 如果能时刻看到下载状态就太好了。
目的
- 节约时间
- 时刻掌握下载情况和程序状态
示例:(基于tqdm 手动更新)
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor, wait, as_completed, ALL_COMPLETED
video_path = []
def _download(path):
print(path)
with ThreadPoolExecutor(max_workers=50) as t:
all_task = [t.submit(_download, path) for path in video_path]
with tqdm(total=len(all_task)) as pbar:
pbar.set_description('Processing:')
for i in as_completed(all_task):
if i.done():
# 进行进度更新, 完成一个任务更新一次
pbar.update(1)
原理
多线程获取任务执行结果 as_completed 函数
获取线程池中已经运行完的任务结果
from concurrent.futures import ThreadPoolExecutor, as_completed
from time import sleep
def method(times):
sleep(times)
print('sleep {} secondes'.format(times))
return times
pool = ThreadPoolExecutor(max_workers=2)
seconds = [i for i in range(10)]
tasks = [pool.submit(method, (second)) for second in seconds]
# as_completed函数会将运行完的任务一个一个yield出来
# 它返回任务的结果与提交任务的顺序无关,谁先执行完返回谁
for future in as_completed(tasks):
print(future.result())
进度条 tqdm 模块
是python进度条库, 主要分为两种运行模式:
tqdm(iterator) 基于迭代对象
for i in tqdm(range(100), desc='Processing'):
time.sleep(0.5)
手动进行更新
with tqdm(total=200) as pbar:
pbar.set_description('Processing:')
# total表示总的项目, 循环的次数20*10(每次更新数目) = 200(total)
for i in range(20):
# 进行动作, 这里是过0.1s
time.sleep(0.1)
# 进行进度更新, 这里设置10个
pbar.update(10)
参数
- iterable: 可迭代的对象, 在手动更新时不需要进行设置
- desc: 字符串, 左边进度条描述文字
- total: 总的项目数
- leave: bool值, 迭代完成后是否保留进度条
- file: 输出指向位置, 默认是终端, 一般不需要设置
- ncols: 调整进度条宽度, 默认是根据环境自动调节长度, 如果设置为0, 没有进度条, 只有输出的信息
- unit: 描述处理项目的文字, 默认是’it’, 例如: 100 it/s, 处理照片的话设置为’img’ ,则为 100 img/s
- unit_scale: 自动根据国际标准进行项目处理速度单位的换算, 例如 100000 it/s >> 100k it/s
示例:
import time
from tqdm import tqdm
# 发呆0.5s
def action():
time.sleep(0.5)
with tqdm(total=100000, desc='Example', leave=True, ncols=100, unit='B', unit_scale=True) as pbar:
for i in range(10):
# 发呆0.5秒
action()
# 更新发呆进度
pbar.update(10000)
本文借鉴: