Python 定时任务

Python 实现定时任务

第三方库:

  • schedule

  • APScheduler

1. schedule

1.1 安装

安装:

pip install schedule
conda install schedule

1.2 简介

代码模板 1:每隔固定的时间运行程序

schedule.every(interval=1).(second, minute, hour, day).do(job_func, *args, **kwargs)
schedule.every(interval).(seconds, minutes, hours, days, weeks).do(job_func, *args, **kwargs)

代码模板 2:在每天(或每周的某一天)指定的时间运行程序

# 在 每周一 上午 5 点运行程序
schedule.every().monday.at("05:00").do(job_func, *args, **kwargs)
  • monday 可替换为 day(表示每天), tuesdaywednesday

  • "05:00" 可替换为 "07:01""13:00" 等,表示具体的时间

主要参数:

  • interval:指定单位的间隔

    • interval=1,可以使用单数单位(如:second)或复数单位(如:seconds

    • interval>=2,必须使用复数单位(如:seconds

  • secondsecondsminuteminutes 等:时间单位

  • job_func, *args, **kwargs:指定的任务和传入 job_func 的参数

主要方法:

  • schedule.clear():清除所有的任务

  • cancel_job(job):取消指定的任务

  • at():在指定的时间执行

1.3 实例

实例 1:定义 2 个运行的函数

import time
import datetime
import schedule

def test_func_1():
    print('test_func_1', datetime.datetime.now())  # 在函数的开始位置,输出当前时间
    time.sleep(2)  # 函数 1 的运行时间: 2 秒

def test_func_2():
    print('test_func_2', datetime.datetime.now())
    time.sleep(3)  # 函数 2 的运行时间: 3 秒

实例 2:每隔 10 秒运行一次

schedule.clear()  # 清楚所有 jobs
schedule.every(10).seconds.do(test_func_1)  # 每隔 10 秒运行一次 test_func_1

while True:    # 保持程序一直运行
    schedule.run_pending()
# Output:  test_func_1 2022-05-31 15:37:05.315094
# Output:  test_func_1 2022-05-31 15:37:17.318548
# Output:  test_func_1 2022-05-31 15:37:29.322773
# Output:  test_func_1 2022-05-31 15:37:41.326181

从输出的结果可以看出,实际程序的运行间隔为 12 秒,等于 10 秒的设定间隔 加上 2 秒的程序运行时间

实例 3:多任务同时执行

schedule.clear()
schedule.every(10).seconds.do(test_func_1)  # Job 1:间隔 10s,运行时间 2s
schedule.every(5).seconds.do(test_func_2)   # Job 2:间隔 5s,运行时间 3s

while True:
    schedule.run_pending()
# Output:  test_func_2 2022-05-31 16:28:19.147348
# Output:  test_func_1 2022-05-31 16:28:24.147257
# Output:  test_func_2 2022-05-31 16:28:27.150793
# Output:  test_func_2 2022-05-31 16:28:35.154721
# Output:  test_func_1 2022-05-31 16:28:38.159896
# Output:  test_func_2 2022-05-31 16:28:43.159871
# Output:  test_func_1 2022-05-31 16:28:50.163727

1.3 缺点

  • 实际间隔 = 设定间隔 + 程序运行时间

  • 对于多任务,任务存在执行的先后顺序

2. APScheduler

2.1 安装

pip install apscheduler
conda install apscheduler

2.1 四个基本对象

  1. 触发器(triggers):
  • 指定的触发方式,有两种触发方式:

    • 按照时间间隔(interval)触发

    • 按照指定时间(crontab)触发

  • 每个任务都有自己的触发器。

  1. 任务存储器(job stores):
  • 任务存储器是可以存储任务的地方,默认情况下任务保存在内存,也可将任务保存在各种数据库中。

  • 任务存储进去后,会进行序列化,然后也可以反序列化提取出来,继续执行。

  1. 执行器(executors):
  • 执行器的目的是安排任务到线程池或者进程池中运行的。
  1. 调度器(schedulers):
  • 任务调度器是属于整个调度的总指挥官。通过合理安排作业存储器、执行器、触发器进行工作,并进行添加和删除任务等。调度器通常是只有一个的。

  • 开发人员很少直接操作触发器、存储器、执行器等。因为这些都由调度器自动来实现了。

2.1.1 触发器

A. date 触发器

主要参数:

  • run_datedatetime 类型或 str 类型(ISO 8601 格式)

  • timezonedatetime.tzinfostr 类型,时区

实例:date 触发器

from datetime import date
from apscheduler.schedulers.blocking import BlockingScheduler

def my_job(text):
    print(text)

sched = BlockingScheduler()
sched.add_job(my_job, 'date', run_date=date(2009, 11, 6), args=['text'])
sched.start()
# The job will be executed on November 6th, 2009 at 16:30:05
sched.add_job(my_job, 'date', run_date=datetime(2009, 11, 6, 16, 30, 5), args=['text'])
sched.add_job(my_job, 'date', run_date='2009-11-06 16:30:05', args=['text'])

B. interval 触发器

主要参数:

  • weeks (int) : number of weeks to wait
  • days (int) : number of days to wait
  • hours (int) : number of hours to wait
  • minutes (int) : number of minutes to wait
  • seconds (int) : number of seconds to wait
  • start_date (datetime|str) : starting point for the interval calculation
  • end_date (datetime|str) : latest possible date/time to trigger on
  • timezone (datetime.tzinfo|str) : time zone to use for the date/time calculations
  • jitter (int|None) : delay the job execution by jitter seconds at most

实例:interval 触发器

# The same as before, but starts on 2010-10-10 at 9:30 and stops on 2014-06-15 at 11:00
sched.add_job(job_func, 'interval', hours=2, start_date='2010-10-10 09:30:00', end_date='2014-06-15 11:00:00')

C. cron 触发器

类似于 UNIX 系统中的 cron scheduler works。使用方法参见官方文档

主要参数

  • year (int|str) – 4-digit year
  • month (int|str) – month (1-12)
  • day (int|str) – day of month (1-31)
  • week (int|str) – ISO week (1-53)
  • day_of_week (int|str) – number or name of weekday (0-6 or mon, tue, wed, thu, fri, sat, sun)
  • hour (int|str) – hour (0-23)
  • minute (int|str) – minute (0-59)
  • second (int|str) – second (0-59)
  • start_date (datetime|str) – earliest possible date/time to trigger on (inclusive)
  • end_date (datetime|str) – latest possible date/time to trigger on (inclusive)
  • timezone (datetime.tzinfo|str) – time zone to use for the date/time calculations (defaults to scheduler timezone)
  • jitter (int|None) – delay the job execution by jitter seconds at most

表达式:参见官方文档

实例:cron 触发器

# Schedules job_func to be run on the third Friday of June, July, August, November and December at 00:00, 01:00, 02:00 and 03:00
sched.add_job(job_function, 'cron', month='6-8,11-12', day='3rd fri', hour='0-3')

2.2 任务

Job 类的主要参数

  • id (str) – the unique identifier of this job
  • name (str) – the description of this job
  • func – the callable to execute
  • args (tuple|list) – positional arguments to the callable
  • kwargs (dict) – keyword arguments to the callable

Job 类的主要方法

  • add_job(job):
  • get_all_jobs(job): Returns a list of all jobs in this job store.
  • lookup_job(job_id):
  • update_job(job):
  • remove_all_jobs():
  • remove_job(job_id):
  • shutdown()
  • start(scheduler, alias):

2.3 测试实例

from apscheduler.schedulers.blocking import BlockingScheduler
scheduler = BlockingScheduler()  # 创建调度器:BlockingScheduler
scheduler.add_job(test_func_1, 'interval', seconds=5, id='job_1')   # 添加 job 1,时间间隔 5s
scheduler.add_job(test_func_2, 'interval', seconds=10, id='job_2')  # 添加 job 2,时间间隔 10s
scheduler.start()
# Output:  test_func_1 2022-06-01 01:04:00.682053
# Output:  test_func_1 2022-06-01 01:04:05.682940
# Output:  test_func_2 2022-06-01 01:04:05.685737
# Output:  test_func_1 2022-06-01 01:04:10.685675
# Output:  test_func_1 test_func_2 2022-06-01 01:04:15.684472 2022-06-01 01:04:15.691071
# Output:  test_func_1 2022-06-01 01:04:20.690736
# Output:  test_func_1 2022-06-01 01:04:25.683002 test_func_2 2022-06-01 01:04:25.683584

从测试的结果来看,可以很好的满足预期要求

参考资料

python任务调度之schedule, 知乎, site

python定时任务最强框架APScheduler详细教程, 知乎, site

Python3-定时任务四种实现方式, 51CTO博客, site

posted @ 2022-06-01 00:31  veager  阅读(433)  评论(0)    收藏  举报