Python定時任務(上)

在項目中,我們可能遇到有定時任務的需求。其一:定時執行任務。例如每天早上 8 點定時推送早報。其二:每隔一個時間段就執行任務。比如:每隔一個小時提醒自己起來走動走動,避免長時間坐著。今天,我跟大家分享下 Python 定時任務的實現方法。

1

第一種辦法是最簡單又最暴力。那就是在一個死循環中,使用線程睡眠函數 sleep()。

from datetime import datetime
import time


每個 10 秒列印當前時間。

def timedTask():
while True:
print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
time.sleep(10)

if __name__ == __main__:
timedTask()

這種方法能夠執行固定間隔時間的任務。如果timedTask()函數之後還有些操作,我們還使用死循環 + 阻塞線程。這會使得timedTask()一直佔有 CPU 資源,導致後續操作無法執行。我建議謹重使用。

2

既然第一種方法暴力,那麼有沒有比較優雅地方法?答案是肯定的。Python 標準庫 threading 中有個 Timer 類。它會新啟動一個線程來執行定時任務,所以它是非阻塞函式。

如果你有使用多線程的話,需要關心線程安全問題。那麼你可以選使用threading.Timer模塊。

from datetime import datetime
from threading import Timer
import time

每個 10 秒列印當前時間。

def timedTask():

第一個參數: 延遲多長時間執行任務(單位: 秒)
第二個參數: 要執行的任務, 即函數
第三個參數: 調用函數的參數(tuple)

Timer(10, task, ()).start()

# 定時任務
def task():
print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

if __name__ == __main__:
timedTask()
while True:
print(time.time())
time.sleep(5)

運行結果:

1512486945.1196375
1512486950.119873
2017-12-05 23:15:50
1512486955.133385

3

第三種方式是也是使用標準庫中sched模塊。sched 是事件調度器,它通過 scheduler 類來調度事件,從而達到定時執行任務的效果。

sched庫使用起來也是非常簡單。

1)首先構造一個sched.scheduler

它接受兩個參數:timefuncdelayfunc。timefunc 應該返回一個數字,代表當前時間,delayfunc 函數接受一個參數,用於暫停運行的時間單元。

一般使用默認參數就行,即傳入這兩個參數 time.timetime.sleep.當然,你也可以自己實現時間暫停的函數。

2)添加調度任務

scheduler 提供了兩個添加調度任務的函數:

  • enter(delay, priority, action, argument=(), kwargs={})

該函數可以延遲一定時間執行任務。delay 表示延遲多長時間執行任務,單位是秒。priority為優先順序,越小優先順序越大。兩個任務指定相同的延遲時間,優先順序大的任務會向被執行。action 即需要執行的函數,argumentkwargs 分別是函數的位置和關鍵字參數。

  • scheduler.enterabs(time, priority, action, argument=(), kwargs={})

添加一項任務,但這個任務會在 time 這時刻執行。因此,time 是絕對時間.其他參數用法與 enter() 中的參數用法是一致。

3)把任務運行起來

調用 scheduler.run()函數就完事了。

下面是 sche 使用的簡單示例:

from datetime import datetime
import sched
import time

每個 10 秒列印當前時間。

def timedTask():
# 初始化 sched 模塊的 scheduler 類
scheduler = sched.scheduler(time.time, time.sleep)
# 增加調度任務
scheduler.enter(10, 1, task)
# 運行任務
scheduler.run()

# 定時任務
def task():
print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

if __name__ == __main__:
timedTask()

值得注意的是: scheduler 中的每個調度任務只會工作一次,不會無限循環被調用。如果想重複執行同一任務, 需要重複添加調度任務即可。

推薦閱讀:

《Python 基礎》

徹底理解Iterable、Iterator、generator

Python 面試寶典

使用 Python 生成二維碼

Python中「is」和「==」的區別

《爬蟲相關的文章》

盤點一些網站的反爬蟲機制

想提高爬蟲效率?aiohttp 了解下

爬蟲與反爬蟲的博弈

多線程爬取 unsplash 圖庫

爬取《Five Hundred Miles》在網易雲音樂的所有評論

學會運用爬蟲框架 Scrapy (五) —— 部署爬蟲

學會運用爬蟲框架 Scrapy (四) —— 高效下載圖片

學會運用爬蟲框架 Scrapy (三)

爬取網易雲音樂精彩評論

學會運用爬蟲框架 Scrapy (二)-爬取 V電影

我爬取豆瓣影評,告訴你《復仇者聯盟3》在講什麼?

爬蟲實戰一:爬取噹噹網所有 Python 書籍

「幹將莫邪」 —— Xpath 與 lxml 庫

爬蟲實戰二:爬取電影天堂的最新電影

本文原創發佈於微信公眾號「極客猴」,歡迎關注第一時間獲取更多原創分享

極客猴】每周堅持分享 Python 原創乾貨的公眾號。包括基礎入門,進階技巧,網路爬蟲,數據分析, Web 應用開發等,歡迎關注。

推薦閱讀:

TAG:Python | Python入門 | Python開發 |