APScheduler简介
在平常的工作中几乎有一半的功能模块都需要定时任务来推动,例如项目中有一个定时统计程序,定时爬出网站的URL程序,定时检测钓鱼网站的程序等等,都涉及到了关于定时任务的问题,第一时间想到的是利用time模块的time.sleep()方法使程序休眠来达到定时任务的目的,虽然这样也可以,但是总觉得不是那么的专业,^_^所以就找到了python的定时任务模块APScheduler:
APScheduler基于Quartz的一个Python定时任务框架,实现了Quartz的所有功能,使用起来十分方便。提供了基于日期、固定时间间隔以及crontab类型的任务,并且可以持久化任务。基于这些功能,我们可以很方便的实现一个python定时任务系统。
安装
1、利用pip进行安装
1 | |
2、源码安装(https://pypi.python.org/pypi/APScheduler/)
1 | |
APScheduler有四种组成部分:
触发器(trigger)包含调度逻辑,每一个作业有它自己的触发器,用于决定接下来哪一个作业会运行。除了他们自己初始配置意外,触发器完全是无状态的。
作业存储(job store)存储被调度的作业,默认的作业存储是简单地把作业保存在内存中,其他的作业存储是将作业保存在数据库中。一个作业的数据讲在保存在持久化作业存储时被序列化,并在加载时被反序列化。调度器不能分享同一个作业存储。
执行器(executor)处理作业的运行,他们通常通过在作业中提交制定的可调用对象到一个线程或者进城池来进行。当作业完成时,执行器将会通知调度器。
调度器(scheduler)是其他的组成部分。你通常在应用只有一个调度器,应用的开发者通常不会直接处理作业存储、调度器和触发器,相反,调度器提供了处理这些的合适的接口。配置作业存储和执行器可以在调度器中完成,例如添加、修改和移除作业。
简单应用:
1 2 3 4 5 6 7 8 9 | |
上面的例子表示每隔5s执行一次my_job函数,输出当前时间信息
操作作业
1. 添加作业
上面是通过add_job()来添加作业,另外还有一种方式是通过scheduled_job()修饰器来修饰函数
1 2 3 4 5 6 7 8 9 10 | |
2. 移除作业
1 2 3 4 5 | |
3. 暂停和恢复作业
暂停作业:
1 2 | |
恢复作业:
1 2 | |
4. 获得job列表
获得调度作业的列表,可以使用
get_jobs()
来完成,它会返回所有的job实例。或者使用
print_jobs()
来输出所有格式化的作业列表。也可以利用get_job(任务ID)获取指定任务的作业列表
1 2 3 | |
5. 关闭调度器
默认情况下调度器会等待所有正在运行的作业完成后,关闭所有的调度器和作业存储。如果你不想等待,可以将wait选项设置为False。
1 2 | |
作业运行的控制(trigger)
add_job的第二个参数是trigger,它管理着作业的调度方式。它可以为date, interval或者cron。对于不同的trigger,对应的参数也相同。
(1). cron定时调度(某一定时时刻执行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
参数的取值格式:
例子:
1 2 3 4 5 6 7 8 9 10 11 | |
(2). interval 间隔调度(每隔多久执行)
1 2 3 4 5 6 7 8 | |
例子:
1 2 | |
(3). date 定时调度(作业只会执行一次)
1 2 | |
例子:
1 2 3 4 | |
具体事例代码如下:
# -*- coding: utf-8 -*-
import datetime
"""
date:一次性任务,即只执行一次任务
interval:循环任务,即按照时间间隔执行任务
cron:定时任务,即在每个时间段执行任务
"""
from apscheduler.schedulers.blocking import BlockingScheduler
# 指定触发器为interval:
# interval:循环任务,即按照时间间隔执行任务。
'''
参数如下:
seconds (int) – 秒
minutes (int) – 分钟
hours (int) – 小时
days (int) – 日
weeks (int) – 周
start_date (datetime|str) – 启动开始时间
end_date (datetime|str) – 最后结束时间
timezone (datetime.tzinfo|str) – 时区
'''
def job1():
print("job 1")
def job2(name):
print("hello %s" % name)
schedule = BlockingScheduler()
# # 每秒执行一次 有参数
schedule.add_job(func=job2, args=('interval----------',), trigger='interval', seconds=1)
# # 每秒执行一次 无参数
schedule.add_job(func=job1, trigger='interval', seconds=1)
schedule.start() # 启动定时器
# 执行触发器为date:
# 延时五秒后执行一次
'''
date:一次性任务,即只执行一次任务。
参数如下:
next_run_time (datetime|str) – 下一次任务执行时间
timezone (datetime.tzinfo|str) – 时区
'''
schedule.add_job(func=job2, args=('date--------',), trigger='date',
next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=5))
schedule.start() # 启动定时器
# 指定触发器为cron:
'''
cron:定时任务,即在每个时间段执行任务。
参数如下:
second (int|str) – 秒 (0-59)
minute (int|str) – 分钟 (0-59)
hour (int|str) – 小时 (0-23)
day_of_week (int|str) – 一周中的第几天 (0-6 or mon,tue,wed,thu,fri,sat,sun)
day (int|str) – 日 (1-31)
week (int|str) – 一年中的第几周 (1-53)
month (int|str) – 月 (1-12)
year (int|str) – 年(四位数)
start_date (datetime|str) – 最早开始时间
end_date (datetime|str) – 最晚结束时间
timezone (datetime.tzinfo|str) – 时区
'''
# 在1月,2-3月,每天的9上午9点点,每秒钟执行一次任务,下面2种写法都可以
# schedule.add_job(func=job2, args=('cron--------',), trigger='cron', month='1,2-3', day='*', hour='9', second='*',
# timezone='Asia/Shanghai')
schedule.add_job(func=job2, args=('cron--------',), trigger='cron', month='1,2-3', day='*', hour='9', second='*/1',
timezone='Asia/Shanghai')
schedule.start() # 启动定时器