最新Python?APScheduler?定時(shí)任務(wù)詳解
一、基本概念
APScheduler全稱Advanced Python Scheduler 作用為在指定的時(shí)間規(guī)則執(zhí)行指定的作業(yè)。
- 指定時(shí)間規(guī)則的方式可以是間隔多久執(zhí)行,可以是指定日期時(shí)間的執(zhí)行,也可以類似Linux系統(tǒng)中Crontab中的方式執(zhí)行任務(wù)。
- 指定的任務(wù)就是一個(gè)Python函數(shù)。
1.1、 觸發(fā)器:triggers
用于設(shè)定觸發(fā)任務(wù)的條件: 觸發(fā)器包含調(diào)度邏輯。每個(gè)任務(wù)都有自己的觸發(fā)器,用于確定何時(shí)應(yīng)該運(yùn)行作業(yè)。除了初始配置之外,觸發(fā)器完全是無(wú)狀態(tài)的
1.2、作業(yè)存儲(chǔ)器:job stores
用于存放任務(wù),把任務(wù)存放在內(nèi)存或數(shù)據(jù)庫(kù)中
- 默認(rèn)情況下,任務(wù)存放在內(nèi)存中。也可以配置存放在不同類型的數(shù)據(jù)庫(kù)中。如果任務(wù)存放在數(shù)據(jù)庫(kù)中,那么任務(wù)的存取有一個(gè)序列化和反序列化的過程,同時(shí)修改和搜索任務(wù)的功能也是由任務(wù)儲(chǔ)存器實(shí)現(xiàn)。
- 注意一個(gè)任務(wù)儲(chǔ)存器不要共享給多個(gè)調(diào)度器,否則會(huì)導(dǎo)致狀態(tài)混亂
1.3、執(zhí)行器 executors
用于執(zhí)行任務(wù),可以設(shè)定執(zhí)行模式為單線程或線程池:任務(wù)會(huì)被執(zhí)行器放入線程池或進(jìn)程池去執(zhí)行,執(zhí)行完畢后,執(zhí)行器會(huì)通知調(diào)度器。
1.4、調(diào)度器 schedulers
把上方三個(gè)組件作為參數(shù),通過創(chuàng)建調(diào)度器實(shí)例來運(yùn)行:一個(gè)調(diào)度器由上方三個(gè)組件構(gòu)成,一般來說,一個(gè)程序只要有一個(gè)調(diào)度器就可以了。開發(fā)者也不必直接操作任務(wù)儲(chǔ)存器、執(zhí)行器以及觸發(fā)器,因?yàn)檎{(diào)度器提供了統(tǒng)一的接口,通過調(diào)度器就可以操作組件,比如任務(wù)的增刪改查。

二、調(diào)度器詳解
BlockingScheduler: 阻塞式調(diào)度器:適用于只跑調(diào)度器的程序。BackgroundScheduler: 后臺(tái)調(diào)度器:適用于非阻塞的情況,調(diào)度器會(huì)在后臺(tái)獨(dú)立運(yùn)行AsyncIOScheduler: AsyncIO調(diào)度器,適用于應(yīng)用使用AsnycIO的情況。GeventScheduler: Gevent調(diào)度器,適用于應(yīng)用通過Gevent的情況。TornadoScheduler: Tornado調(diào)度器,適用于構(gòu)建Tornado應(yīng)用。TwistedScheduler:Twisted調(diào)度器,適用于構(gòu)建Twisted應(yīng)用。QtScheduler: Qt調(diào)度器,適用于構(gòu)建Qt應(yīng)用。
2.1、APScheduler有三種內(nèi)置的觸發(fā)器
date:日期:觸發(fā)任務(wù)運(yùn)行的具體日期interval: 間隔:觸發(fā)任務(wù)運(yùn)行的時(shí)間間隔cron: 周期:觸發(fā)任務(wù)運(yùn)行的周期
2.2、觸發(fā)器公共參數(shù)
id:啟動(dòng)任務(wù)的ID具有唯一性name: 設(shè)置啟動(dòng)任務(wù)的名稱coalesce:當(dāng)由于某種原因?qū)е履硞€(gè)job積攢了好幾次沒有實(shí)際運(yùn)行(比如說系統(tǒng)掛了5分鐘后恢復(fù),有一個(gè)任務(wù)是每分鐘跑一次的,按道理說這5分鐘內(nèi)本來是“計(jì)劃”運(yùn)行5次的,但實(shí)際沒有執(zhí)行),如果coalesce為True,下次這個(gè)job被submit給executor時(shí),只會(huì)執(zhí)行1次,也就是最后這次,如果為False,那么會(huì)執(zhí)行5次(不一定,因?yàn)檫€有其他條件,看后面misfire_grace_time的解釋)max_instance: 就是說同一個(gè)job同一時(shí)間最多有幾個(gè)實(shí)例再跑,比如一個(gè)耗時(shí)10分鐘的job,被指定每分鐘運(yùn)行1次,如果我們max_instance值為5,那么在第6~10分鐘上,新的運(yùn)行實(shí)例不會(huì)被執(zhí)行,因?yàn)橐呀?jīng)有5個(gè)實(shí)例在跑了misfire_grace_time:設(shè)想和上述coalesce類似的場(chǎng)景,如果一個(gè)job本來14:00有一次執(zhí)行,但是由于某種原因沒有被調(diào)度上,現(xiàn)在14:01了,這個(gè)14:00的運(yùn)行實(shí)例被提交時(shí),會(huì)檢查它預(yù)訂運(yùn)行的時(shí)間和當(dāng)下時(shí)間的差值(這里是1分鐘),大于我們?cè)O(shè)置的30秒限制,那么這個(gè)運(yùn)行實(shí)例不會(huì)被執(zhí)行。replace_existing: 如果調(diào)度的job在一個(gè)持久化的存儲(chǔ)器里,當(dāng)初始化應(yīng)用程序時(shí),必須要為job定義一個(gè)顯示的ID并使用replace_existing=True, 否則每次應(yīng)用程序重啟時(shí)都會(huì)得到那個(gè)job的一個(gè)新副本
2.3、date內(nèi)置觸發(fā)器
date 是最基本的一種調(diào)度,作業(yè)任務(wù)只會(huì)執(zhí)行一次。它表示特定的時(shí)間點(diǎn)觸發(fā)。它的參數(shù)如下:
| 參數(shù) | 說明 |
|---|---|
| run_date (datetime 或 str) | 作業(yè)的運(yùn)行日期或時(shí)間 |
| timezone (datetime.tzinfo 或 str) | 指定時(shí)區(qū) |
from datetime import datetime
from datetime import date
from apscheduler.schedulers.blocking import BlockingScheduler
def job(text):
print(text)
scheduler = BlockingScheduler()
# 在 2019-8-30 運(yùn)行一次 job 方法
scheduler.add_job(job, 'date', run_date=date(2022, 4, 9), args=['text1'], id="1", coalesce=True, max_instances=1)
# 在 2019-8-30 01:00:00 運(yùn)行一次 job 方法
scheduler.add_job(job, 'date', run_date=datetime(2022, 4, 9, 17, 40, 58), args=['text2'], id="2", coalesce=True, max_instances=1)
# 在 2019-8-30 01:00:01 運(yùn)行一次 job 方法
scheduler.add_job(job, 'date', run_date='2022-4-9 17:41:00', args=['text3'], id="3", coalesce=True, max_instances=1)
scheduler.start()2.4、interval 周期觸發(fā)任務(wù)
| 參數(shù) | 說明 |
|---|---|
weeks (int) | 間隔幾周 |
days (int) | 間隔幾天 |
hours (int) | 間隔幾小時(shí) |
minutes (int) | 間隔幾分鐘 |
seconds (int) | 間隔多少秒 |
start_date (datetime 或 str) | 開始日期 |
end_date (datetime 或 str) | 結(jié)束日期 |
timezone (datetime.tzinfo 或str) | 時(shí)區(qū) |
@sched.scheduled_job(
"interval", id=spider_job_name + "_bg_data", coalesce=True, max_instances=1, minutes=20
)
def tick_rzjg_detail_xq():
"""
快速完成
:return:
"""
each = "rzjg_bg_data"
cmd_str = f"cd {ROOT} && bash run_spider.sh {each} --loglevel=INFO"
print(cmd_str)
os.system(cmd_str)
def func():
print("Press Ctrl+C to exit")
# 直接觸發(fā)一次
tick_rzjg_detail_xq()
try:
sched.start()
except (KeyboardInterrupt, SystemExit):
pass
if __name__ == "__main__":
func()2.5、cron 觸發(fā)器 在特定時(shí)間周期性地觸發(fā),和Linux crontab格式兼容。
它是功能最強(qiáng)大的觸發(fā)器
| 參數(shù) | 說明 |
|---|---|
year (int 或 str) | 年,4位數(shù)字 |
month (int 或 str) | 月 (范圍1-12) |
day (int 或 str) | 日 (范圍1-31) |
week (int 或 str) | 周 (范圍1-53) |
day_of_week (int 或 str) | 周內(nèi)第幾天或者星期幾 (范圍0-6 或者 mon,tue,wed,thu,fri,sat,sun) |
hour (int 或 str) | 時(shí) (范圍0-23) |
minute (int 或 str) | 分 (范圍0-59) |
second (int 或 str) | 秒 (范圍0-59) |
start_date (datetime 或 str) | 最早開始日期(包含) |
end_date (datetime 或 str) | 最晚結(jié)束時(shí)間(包含) |
timezone (datetime.tzinfo 或str) | 指定時(shí)區(qū) |
| 表達(dá)式 | 參數(shù)類型 | 描述 |
|---|---|---|
| * | 所有 | 通配符。例:minutes=*即每分鐘觸發(fā) |
| */a | 所有 | 可被a整除的通配符 |
| a-b | 所有 | 范圍a-b觸發(fā) |
| a-b/c | 所有 | 范圍a-b,且可被c整除時(shí)觸發(fā) |
| xth y | 日 | 第幾個(gè)星期幾觸發(fā)。x為第幾個(gè),y為星期幾 |
| last x | 日 | 一個(gè)月中,最后個(gè)星期幾觸發(fā) |
| last | 日 | 一個(gè)月最后一天觸發(fā) |
| x,y,z | 所有 | 組合表達(dá)式,可以組合確定值或上方的表達(dá)式 |
import time
from apscheduler.schedulers.blocking import BlockingScheduler
def job(text):
t = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
print('{} --- {}'.format(text, t))
scheduler = BlockingScheduler()
# 在每天22點(diǎn),每隔 1分鐘 運(yùn)行一次 job 方法
scheduler.add_job(job, 'cron', hour=22, minute='*/1', args=['job1'])
# 在每天22和23點(diǎn)的25分,運(yùn)行一次 job 方法
scheduler.add_job(job, 'cron', hour='22-23', minute='25', args=['job2'])
# 在每天 8 點(diǎn),運(yùn)行一次 job 方法
scheduler.add_job(job, 'cron', hour='8', args=['job2'])
# 在每天 8 點(diǎn) 20點(diǎn),各運(yùn)行一次 job 方法 設(shè)置最大運(yùn)行實(shí)例數(shù)
scheduler.add_job(job, 'cron', hour='8, 20', minute=30, max_instances=4)
scheduler.start()到此這篇關(guān)于Python APScheduler 定時(shí)任務(wù)詳解的文章就介紹到這了,更多相關(guān)Python APScheduler 定時(shí)任務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python輕量級(jí)定時(shí)任務(wù)調(diào)度APScheduler的使用
- Python apscheduler實(shí)現(xiàn)定時(shí)任務(wù)的方法詳解
- Python實(shí)現(xiàn)定時(shí)任務(wù)利器之a(chǎn)pscheduler使用詳解
- Python flask框架定時(shí)任務(wù)apscheduler應(yīng)用介紹
- Python定時(shí)任務(wù)框架APScheduler安裝使用詳解
- Python使用apscheduler模塊設(shè)置定時(shí)任務(wù)的實(shí)現(xiàn)
- 從入門到精通詳解Python APScheduler實(shí)現(xiàn)定時(shí)任務(wù)的完整指南
相關(guān)文章
Django如何使用asyncio協(xié)程和ThreadPoolExecutor多線程
這篇文章主要介紹了Django如何使用asyncio協(xié)程和ThreadPoolExecutor多線程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
Python的反射函數(shù)與內(nèi)省工具深入解析
這篇文章主要為大家介紹了Python的反射函數(shù)與內(nèi)省工具深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
解決python環(huán)境無(wú)法安裝 exceptions的問題(含錯(cuò)誤原因分析)
pip install exceptions失敗的根本原因是?exceptions模塊在Python 3.x中已被移除,因此無(wú)法通過pip安裝,本文給大家介紹解決python環(huán)境無(wú)法安裝exceptions的問題,感興趣的朋友跟隨小編一起看看吧2025-09-09
Python+selenium 獲取一組元素屬性值的實(shí)例
今天小編就為大家分享一篇Python+selenium 獲取一組元素屬性值的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-06-06
python3+openCV 獲取圖片中文本區(qū)域的最小外接矩形實(shí)例
這篇文章主要介紹了python3+openCV 獲取圖片中文本區(qū)域的最小外接矩形實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-06-06
利用Selenium添加cookie實(shí)現(xiàn)自動(dòng)登錄的示例代碼(fofa)
這篇文章主要介紹了利用Selenium添加cookie實(shí)現(xiàn)自動(dòng)登錄的示例代碼(fofa),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
Python 如何優(yōu)雅的將數(shù)字轉(zhuǎn)化為時(shí)間格式的方法
這篇文章主要介紹了Python 如何優(yōu)雅的將數(shù)字轉(zhuǎn)化為時(shí)間格式的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09

