Pythonメモ torinaブログ

このブログはDjangoとBootstrap4で作成されました
ソースコード

Pythonで進捗バーを表示する(tqdm)

プログラミング関連 tqdm
約424日前 2016年1月31日5:32
tqdmを使うことで、簡単に進捗バーを作成できます。

requestsとtqdmを使った進捗バー
https://torina.top/main/184/

printだけで作る進捗バー
https://torina.top/main/263/

インストール
pip install tqdm


公式はこちら
https://github.com/tqdm/tqdm

イテラブルなオブジェクトを、tqdm()で囲むことができます
サンプル
from time import sleep
from tqdm import tqdm


for i in tqdm(range(100)):
    sleep(0.1)



このようになります


上の書き方が見た目的にうるさい、と思うならばこういう書き方もできます
from time import sleep
from tqdm import tqdm

my_bar = tqdm(range(100))
for i in my_bar:
    sleep(0.1)




リスト内包表記でも、勿論使えます
[sleep(0.01) for i in tqdm(range(100))]



進捗バーを自分のタイミングで進めることもできます。
pbar = tqdm(total=100)
for i in range(100):
    pbar.update(1)
pbar.close()


totalに合計の値を、.update()に、進めたい数を入れましょう。
ちなみに上記はすぐに処理が終わるので進捗バーは表示されません。


進捗バーに、自分で文字を設定することも可能です。
以下のコードには書いてませんが、pbar.update()と併用も可能です。
import time
from tqdm import tqdm


pbar = tqdm(["a", "b", "c", "d"])
for char in pbar:
    pbar.set_description("Processing %s" % char)
    time.sleep(1)


見た目はこのようになります。



例えば、このブログの記事見出し(h2タグ)を全て取得し、進捗バーで表示したいならば
こんな感じになります


from tqdm import tqdm
import requests
from bs4 import BeautifulSoup


page = 1
url = "http://torina.top/?page={}"
h2s = []

# 数えたら、現在70記事ありました。なので70を入れてます
# ここのtotalとupdateには、適当に入れても割とそれっぽくはなります
pbar = tqdm(total=70)
while True:
    res = requests.get(url.format(page))
    soup = BeautifulSoup(res.text, "html5lib")
    pager_text = soup.find("ul", class_="pagination").text

    # <li><a href="?page=2">NEXT</a></li>が
    # pager_textに含まれていれば、次のページ有
    if not "NEXT" in pager_text:
        break
    h2s += [h2 for h2 in soup.find_all("h2")]
    page += 1
    pbar.update(10)  # 私のブログは、1ページ10記事です

pbar.close()
print("すべてのh2タグを取得しました")




注意点としては、以下のようなコードです。
ジェネレータオブジェクトなど、長さがわからないもの(__len__がない)は少し勝手が変わります。
import time
from tqdm import tqdm


my_range = (x for x in range(10))
for i in tqdm(my_range):
    time.sleep(1)


実行するとこのような表示になります。シンプルになってしまいましたね。むしろ、ちゃんと動作することに感動です。


単純に解決するならば、set_description()で補い、単位となる「unit」を指定しましょう。
import time
from tqdm import tqdm


pbar = tqdm((x for x in range(10)), unit="range")
for i in pbar:
    pbar.set_description("NowRange {0}".format(str(i)))
    time.sleep(1)



表示は以下になります。


tqdmは柔軟に設定が可能なので、色々試してみるとよいでしょう。