談到定時任務,大家可能會優先想到 linux 中的 crontab
,或者 windows 中的任務計劃。這些工具用起來都很方便,但是說出來你可能不信,最近我在生信流程中使用 crontab
命令完成一些自動化操作時,遇到問題了。
不知是不是 crontab
命令不允許有 qsub 的提交操作,還是管理員設置了 crontab
發起任務的用戶沒有節點訪問權限。。。總之,一向很便利的 crontab
命令居然給我挖坑了。于是,我只得自己寫一個定時任務。
當然,核心功能是基于今天的主角 APScheduler
定時任務框架。
安裝
安裝只需要一行命令。
pip3 install apscheduler
如果對Python的環境搭建及模塊安裝還不熟悉,可以看看我寫的另一篇博客 Python環境搭建及模塊安裝 。
運行
首先介紹兩個最常用的調度器:
-
BlockingScheduler
阻塞式調度器:適用于只跑調度器的程序。 -
BackgroundScheduler
后臺調度器:適用于非阻塞的情況,調度器會在后臺獨立運行。
這是人說的話嗎?字我都看得懂,意思一點也不明白。。。
簡單說來,可以把 BlockingScheduler
看成是單線程,如果在程序中僅僅只運行定時任務,那么就應該選擇阻塞式調度器。
而把 BackgroundScheduler
看成是多線程,如果在程序中除了運行定時任務,咱們還想同時做點別的計算啥的,那就應該選擇后臺調度器。
這里我選擇使用 BlockingScheduler
阻塞式調度器,主程序只負責調度定時任務,不執行其他計算等操作。
如下所示:
from apscheduler.schedulers.blocking import BlockingScheduler # 引入模塊
def task():
'''定時任務'''
os.system('python3 spider.py')
if __name__ == '__main__':
scheduler = BlockingScheduler()
# 添加任務
scheduler.add_job(task, 'cron', hour=11, minute=30)
scheduler.start()
運行上面這段代碼,就會在每天的11:30時執行 python3 spider.py
命令。
其中,出現了個新標簽 cron
,這玩意兒叫觸發器,可以設置定時任務觸發的條件,這里就簡單介紹一下這個小東西。
APScheduler有三種內置的觸發器:
date
日期,在某個具體的日期觸發定時任務,僅觸發一次。
# 在2020-1-3這一天的凌晨執行task函數
scheduler.add_job(task, 'date', run_date=date(2020, 1, 3))
# 在1990-12-22 14:30:22時執行task函數
scheduler.add_job(task, 'date', run_date='1990-12-22 14:30:22')
# 未指定時間,則會立即執行
scheduler.add_job(task, 'date')
如上所示,run_date 參數可以是 date型
或 str型
,甚至可以不顯式指定。
interval
間隔,在某個時間間隔后觸發定時任務,間隔觸發無限次。
# 每隔1周3天8時20分5秒執行一次task函數
scheduler.add_job(task, 'interval', weeks=1,days=3,hours=8,minutes=20,seconds=5)
如上所示,weeks、days、hours、minutes、seconds 的參數都是 int型
。
cron
周期,在某個周期內觸發定時任務,循環觸發無限次。
# 每天8時20分執行一次task函數
scheduler.add_job(task, 'cron', hour=8,minute=20)
# 從星期一到星期五的每一天8:20執行一次task函數,直到2100-05-20程序終止
scheduler.add_job(task, 'cron', day_of_week='mon-fri',hour=8,minute=20,end_date='2100-05-20')
該觸發器的規則和 crontab
類似。各參數的說明如下:
參數 | 說明 |
---|---|
year | int型或str,取值四位數的年份,如2020年 |
month | int型或str,取值范圍為1-12月 |
week | int型或str,取值范圍為第1-53周 |
day_of_week | int型或str,表示一周中的第幾天,既可以用0-6表示也可以用其英語縮寫表示(mon,tue,wed,thu,fri,sat,sun) |
day | int型或str,取值范圍為1-31日 |
hour | int型或str,取值范圍為0-23時 |
minute | int型或str,取值范圍為0-59分 |
second | int型或str,取值范圍為0-59秒 |
start_date | datetime型或str,表示開始時間 |
end_date | datetime型或str,表示結束時間 |