↓もし、良かったらSNSでの紹介よろしくお願いします。

【Python】便利なsleepの使い方と実験

bootstrap

time.sleepとは

time.sleepはPythonでスリープ処理を行うメソッドです。
sleepはtimeモジュールのメソッドなので、
timeをインポートして利用します。

import time
time.sleep(5)

ミリ秒のスリープも可能

次のようにミリ秒のスリープも可能です。

time.sleep(0.001)

ただし、OSによっては1/100秒までの精度しかない場合があります。
詳しくは、記事後半「どのくらいの精度か?実験してみた」を参照

どのような場面で利用するのか?

sleepは停止するだけの関数です。
使う機会のない人にとっては、
どういう場面で使うのか疑問だと思います。

sleep関数は次のような場面で利用されます。

  • 一定間隔で実行したい処理があるとき
  • ある時間に実行して欲しい処理があるとき
  • Webページをスクレイピングするとき

一定間隔で実行したい処理があるとき

sleepメソッドを利用すると一定の間隔で処理を行うことができます。

次のコードは1時間おきに、”Hello”を表示します。

import time

while True:
    print("Hello")
        time.sleep(3600)

また、for文で書くと回数の指定ができます。
次のコードは1時間おきに、”Hello”を表示し5回表示すると終了します。

import time

for _ in range(5):
    print("Hello")
        time.sleep(3600)

これらは、UnixのcronやWindowsのタスクスケジューラでも可能ですが、
sleepを使うほうが例外への対応など小回りが効くので便利なことがあります。

ある時間に実行して欲しい処理があるとき

sleepメソッドを利用すると時間指定での処理の実行もできます。

次のコードは2019年01月01日に”Happy New Year”を表示します。

import json
import time
from datetime import datetime

start_time = datetime.strptime("2019/01/01 00:00", '%Y/%m/%d %H:%M')
time_second = (start_time - datetime.now()).seconds
time.sleep(time_second)
print("Happy New Year")

Webページをスクレイピングするとき

同じWebページに複数回アクセスして
情報収集(Webスクレイピング)したいときがあります。

短時間で複数回アクセスすとDos攻撃として認識されて問題になることがあります。
なので、リクエストの間隔をあけるためにsleepを使うと便利です。

import time
import requests

for i in range(1,100):
    requests.get("http://example.com?p=%s" % i)
    time.sleep(10)

どのくらいの精度か?実験してみた

WindowsとMac,CentOSで実験してみました。
どのOSも1/100秒までであれば、精度が保証されていそうです。

Windows10、Python3.5(64bit)

ミリ秒の精度はほぼほぼ保証されているようです。

>>> import time
>>> for _ in range(10):
...   start = time.time()
...   time.sleep(1)
...   end = time.time()
...   print(end-start)
...
1.0003578662872314
1.0005784034729004
1.0001611709594727
1.0005075931549072
1.0007719993591309
1.0001912117004395
1.0002079010009766
1.0018932819366455
1.0006752014160156
1.0001671314239502

Mac Python3.5

Macだと精度が悪くなってしまいました。

>>> import time
>>> for _ in range(10):
...   start = time.time()
...   time.sleep(1)
...   end = time.time()
...   print(end-start)
...
1.0051910877227783
1.005147933959961
1.0017609596252441
1.0051429271697998
1.0001440048217773
1.0051908493041992
1.0054399967193604
1.0024080276489258
1.0053989887237549
1.005387783050537

CentOS Python3.5

CentOSも精度が悪くなってしまいました。

>>> import time
>>> for _ in range(10):
...   start = time.time()
...   time.sleep(1)
...   end = time.time()
...   print(end-start)
...
1.00114393234
1.00115895271
1.0011370182
1.00111508369
1.00114893913
1.00115919113
1.00114011765
1.00113797188
1.00116491318
1.00113797188