APSchedulerでPythonスクリプトを定期実行する
「10分ごとにAPIを叩きたい」「毎朝9時にスクレイピングしたい」――Pythonでそういう定期実行をやるならAPSchedulerが手軽。cronの設定ファイルを書かなくても、Pythonコードの中で完結する。
インストール
pip install apscheduler
一定間隔で実行する(IntervalTrigger)
もっとも基本的な使い方。指定した間隔でジョブを繰り返し実行する。
from apscheduler.schedulers.blocking import BlockingScheduler
def check_price():
print("価格をチェックしました")
scheduler = BlockingScheduler()
scheduler.add_job(check_price, 'interval', minutes=10)
scheduler.start()
minutes=10で10分ごとに実行。seconds=30、hours=1なども指定できる。
特定の時刻に実行する(CronTrigger)
「毎日9時」「毎週月曜」のような指定にはcronトリガーを使う。
from apscheduler.schedulers.blocking import BlockingScheduler
def morning_report():
print("朝のレポートを送信しました")
scheduler = BlockingScheduler()
# 毎日9:00に実行
scheduler.add_job(morning_report, 'cron', hour=9, minute=0)
scheduler.start()
曜日指定もできる:
# 月〜金の18:00に実行
scheduler.add_job(cleanup, 'cron', day_of_week='mon-fri', hour=18)
# 毎週日曜の3:00に実行
scheduler.add_job(weekly_backup, 'cron', day_of_week='sun', hour=3)
複数のジョブを同時に管理する
add_jobを複数回呼ぶだけで、異なるスケジュールのジョブを並行して動かせる。
from apscheduler.schedulers.blocking import BlockingScheduler
def scrape_data():
print("データ収集完了")
def send_report():
print("レポート送信完了")
def cleanup_logs():
print("ログ整理完了")
scheduler = BlockingScheduler()
scheduler.add_job(scrape_data, 'interval', minutes=30)
scheduler.add_job(send_report, 'cron', hour=18, minute=0)
scheduler.add_job(cleanup_logs, 'cron', day_of_week='sun', hour=3)
scheduler.start()
BlockingSchedulerとBackgroundSchedulerの違い
APSchedulerには2つのスケジューラがある。用途で使い分ける。
BlockingScheduler ― スクリプト単体で動かすとき
start()を呼ぶとそこでブロックされる(次の行に進まない)。スケジューラ専用のスクリプトに向いている。
from apscheduler.schedulers.blocking import BlockingScheduler
scheduler = BlockingScheduler()
scheduler.add_job(my_job, 'interval', seconds=30)
scheduler.start()
# ↑ ここでブロック。以降のコードは実行されない
BackgroundScheduler ― Webアプリの中で使うとき
バックグラウンドで動くので、FlaskやFastAPIなど他の処理と併用できる。
from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()
scheduler.add_job(my_job, 'interval', seconds=30)
scheduler.start()
# ↑ ブロックされない。次の行に進む
app.run() # Webアプリなど別の処理を続行
バックグラウンドで動かし続ける
ターミナルを閉じてもスケジューラを動かし続けたい場合:
Mac / Linux:
nohup python scheduler.py > scheduler.log 2>&1 &
ログはscheduler.logに出力される。停止するときは:
ps aux | grep scheduler.py
kill <プロセスID>
Windows(PowerShell):
Start-Process python -ArgumentList "scheduler.py" -WindowStyle Hidden
APSchedulerが向いているケース・向いていないケース
向いている:
- PCが起動している間だけ動けばいい定期タスク
- Webアプリの中でバックグラウンドジョブを回したい
- cronの設定ファイルを書きたくない(Pythonで完結したい)
向いていない:
- PCが落ちている間も確実に実行したい → Cloud Scheduler、Celery Beatなどクラウドサービスを検討
- 大量のジョブを分散処理したい → Celeryのほうが適切
シンプルな定期実行なら、APSchedulerで十分まかなえる。