美文网首页
爬虫定时启动框架apscheduler最快上手指南

爬虫定时启动框架apscheduler最快上手指南

作者: RocheLimit007 | 来源:发表于2018-09-18 23:57 被阅读395次

    我们在使用爬虫脚本抓取数据时通常都会有定时更新的需求,下面跟大家介绍一款python语言中非常流行的定时任务执行框架———apscheduler

    apscheduler简介:

    APScheduler基于Quartz的一个Python定时任务框架,实现了Quartz的所有功能,使用起来十分方便。提供了基于日期、固定时间间隔以及crontab类型的任务,并且可以持久化任务。基于这些功能,我们可以很方便的实现一个python定时任务系统。

    使用方法:

    安装:pip install apscheduler

    重点介绍该框架最实用的两种功能

    功能一:interval: 每隔一段时间执行一次weeks=0 | days=0 | hours=0 | minutes=0 | seconds=0, start_date=None, end_date=None, timezone=None

    功能二:cron:在固定时间点执行一次year=0|month = 0|day = 0|hour = 0|minute = 0|second = 0

    使用例子:

    表示2017年3月22日17时19分07秒执行该程序

    sched.add_job(my_job, 'cron', year=2017,month = 03,day = 22,hour = 17,minute = 19,second = 07)

    #表示任务在6,7,8,11,12月份的第三个星期五的00:00,01:00,02:00,03:00 执行该程序

    sched.add_job(my_job, 'cron', month='6-8,11-12', day='3rd fri', hour='0-3')

    #表示从星期一到星期五5:30(AM)直到2014-05-30 00:00:00

    sched.add_job(my_job(), 'cron', day_of_week='mon-fri', hour=5, minute=30,end_date='2014-05-30')

    #表示每5秒执行该程序一次,相当于interval 间隔调度中seconds = 5

    sched.add_job(my_job, 'cron',second = '*/5')

    demo代码:

    # coding=utf8

    from apscheduler.schedulers.blocking import BlockingScheduler

    import time

    def my_job():  # 需要重复执行的任务

        print("job_start:",time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))

        time.sleep(3)        

        print("job_end:",time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))

    sched = BlockingScheduler()

    # 方式一

    sched.add_job(my_job, 'interval', seconds=6) # 把任务添加到执行队列中,每间隔6s执行一次。

    #方式二

    sched.add_job(my_job, 'corn', hour=0) # 把任务添加到执行队列中,每天零点执行。

    sched.start()  # 任务开始

    以每间隔6s启动一次的任务作为测试案例:

    输出:

    (py3_django) E:\spider\test_ap>python test_ap.py

    Pending jobs:

        my_job (trigger: interval[0:00:06], pending)

    job_start: 2018-09-16 10:25:06

    job_end: 2018-09-16 10:25:09

    job_start: 2018-09-16 10:25:12

    job_end: 2018-09-16 10:25:15

    这时细心的读者可以发现一个有趣的现象,明明之前设置的的间隔时间是6s,但是第一个任务结束到第二个任务开始只隔了3s。由此可以得出一个重要的结论:apscheduler在执行任务时,只要任务开始就计时,而不是等任务结束才计时。

    同时衍生出另一个问题:如果任务执行的时间超过间隔时间会怎样?

    测试二:将demo中的sleep参数改成8,其余不变:

    输出

    Pending jobs:

        my_job (trigger: interval[0:00:06], pending)

    job_start: 2018-09-16 10:51:15

    Execution of job "my_job (trigger: interval[0:00:06], next run at: 2018-09-16 10:51:21 CST)" skipped: maximum number of running instances reached (1)

    job_end: 2018-09-16 10:51:23

    job_start: 2018-09-16 10:51:27

    Execution of job "my_job (trigger: interval[0:00:06], next run at: 2018-09-16 10:51:33 CST)" skipped: maximum number of running instances reached (1)

    job_end: 2018-09-16 10:51:35

    通过以上的测试结果可以得出结论:当任务执行所花费的时间大于间隔时间时,apscheduler会抛出一个异常,但是不会影响任务正常执行。它会自动跳过,开始下轮计时。所以6+6-8=4,第一个任务结束,和下一个任务开始间隔时间为4秒。

    当需要定时执行的代码出现异常会怎样:

    测试三:让被执行的任务抛出一个异常

    输出

    job_start: 2018-09-16 11:04:53

    Job "my_job (trigger: interval[0:00:06], next run at: 2018-09-16 11:04:59 CST)" raised an exception

    Traceback (most recent call last):

      File "C:\Users\lenovo\Anaconda3\envs\py3_django\lib\site-packages\apscheduler\executors\base.py", line 125, in run_job

        retval = job.func(*job.args, **job.kwargs)

      File "test_ap.py", line 21, in my_job

        print(a)

    NameError: name 'a' is not defined

    job_start: 2018-09-16 11:04:59

    Job "my_job (trigger: interval[0:00:06], next run at: 2018-09-16 11:05:05 CST)" raised an exception

    Traceback (most recent call last):

      File "C:\Users\lenovo\Anaconda3\envs\py3_django\lib\site-packages\apscheduler\executors\base.py", line 125, in run_job

        retval = job.func(*job.args, **job.kwargs)

      File "test_ap.py", line 21, in my_job

        print(a)

    NameError: name 'a' is not defined

    由以上的测试结果可以得出一个结论:当被定时执行的任务抛出异常时,定时循环并不会终止,等到下一轮仍然继续执行。

    我们在日常开发中会经常碰到需要修改代码的情况,当我们修改了爬虫代码,在不重新启动定时任务的情况下修改会不会生效呢?经过实践,我发现当采用命令行方式启动修改会生效,直接调用函数改动不会生效。

    测试四:修改代码后,不重启定时任务,修改是否生效。

    # 调用函数启动任务

    代码修改前:

    输出:

    代码修改后:

    输出

    可以看出使用调用函数方法启动时,没有重启定时任务的情况下,修改没有生效。

    # 命令行方式启动

    代码修改前

    输出

    代码修改后

    输出

    由此可以看出,当使用命令行方式启动时,修改代码后,即使没有重新启动定时任务代码的修改是可以生效的,所以如需要频繁修改代码,建议采用命令行的方式启动爬虫。

    相关文章

      网友评论

          本文标题:爬虫定时启动框架apscheduler最快上手指南

          本文链接:https://www.haomeiwen.com/subject/wruxnftx.html