一、需求
在爬取数据过程中,发现不看输出日志是不知道当前的爬取进度,而单纯靠控制台输出日志信息也不方便判断。因此,就想办法给爬取过程加个进度条,实时展示当前的爬取进度。
有了这个需求和想法之后,那如何实现呢?目前有两类实现显示进度条的方案,一种是使用 Python 内置模块,比如 time 模块;另一种是引入第三方专用模块,比如 tqdm 模块,alive-progress 模块等。
二、内置模块实现进度条效果
1、简单进度条
import sys, time
def test_simple():
for i in range(1, 101):
print("\r", end="")
print(f"当前爬取进度:{i}%:", "▋" * (i // 2), end="")
sys.stdout.flush()
time.sleep(0.05)
测试效果:
2、带时间进度条
import time
def test_with_time():
scale = 50
start = time.perf_counter()
for i in range(scale + 1):
progress = "▋" * i
point = "." * (scale - i)
c = (i / scale) * 100
during = time.perf_counter() - start
print("\r{:^3.0f}%【{}->{}】{:.2f}s".format(c, progress, point, during), end="")
time.sleep(0.1)
测试效果:
三、第三方模块实现进度条效果
1、tqdm模块
tqdm 是专门用于快速生成进度条的模块,使用前先下载该模块:
pip install tqdm
import time
from tqdm import tqdm
def test_tqdm():
# tqdm构造器内放入可迭代的对象
for i in tqdm(range(1, 101)):
# do somethings
time.sleep(0.1)
测试效果:
2、alive-progress模块
官网描述:alive-progress 是一个实时展示进度,具有非常酷炫动画效果的进度条工具。
先下载该模块:
pip install alive-progress
实现代码:
from alive_progress import alive_bar
def test_alive_progress(task_num, totals, sleep_time):
for i in range(task_num): # 定义任务数
with alive_bar(totals, bar='blocks', title=f'Task {i + 1}') as bar:
for i in range(totals):
time.sleep(sleep_time)
bar()
test_alive_progress(5, 150, 0.02)
测试效果:
参考了官网的文档,说是运行过程中会有动画效果(实操过程中并未看到呢?)!!
3、其他模块(了解)
3.1 progress模块:Easy progress reporting for Python!
官网地址:progress · PyPI
3.2 PySimpleGUI模块:是一款基于GUI界面展示工具,功能强大,可用于进度条展示。
官网地址:
PySimpleGUI · PyPI
四、总结
其实,第三方模块实现显示进度条功能,底层也是基于内置模块的第二种方式。因此,这里不打算使用第三方库实现进度条,而是采用内置模块实现,选择第二种,并嵌入到代码中。
接下来,将我之前爬取天气数据的方法 operate_selenium() 改造一下,代码如下:
def common_selenium(url, citys, path):
scale = len(citys)
start = time.perf_counter() # 起始计时点
for i in range(len(citys) + 1):
# 进度条相关计算
progress = "▋" * i
point = "." * (scale - i)
c = (i / scale) * 100
# 最后一次列表不存在元素,避免异常,不执行
if i == scale:
pass
else:
browser = webdriver.Chrome() # 使用谷歌浏览器
browser.maximize_window() # 窗口最大化
browser.get(url) # get请求天气网地址
time.sleep(2)
# 搜索指定城市天气
today_weathers = operate_selenium(browser, citys, pos=i, path=path)
# print(f'city:{citys[i]},today_weathers:{today_weathers}')
write_log(today_weathers, citys[i], path)
# 休眠5s,再关闭浏览器
time.sleep(5)
browser.quit()
# 进度条实时显示
during = time.perf_counter() - start
print("\r{:^3.0f}%[{}->{}]{:.2f}s".format(c, progress, point, during), end="")
time.sleep(0.01)
循环爬取城市列表,当爬取到某一座城市的天气信息时,天气数据获取的进度如下:
25 %[▋->...]34.66s
50 %[▋▋->..]51.63s
100%[▋▋▋▋->]69.58s
这下看进度就清晰多了~