为了做一些报表,最近需要每日从爱站上抓取竞争对手的百度流量和移动流量,从我能实现的技术来看,大致有三种实现形式:
第一种不熟悉,还要摸索;第二种数据展现还要自己写,如果用数据库,还要用很原始的连接方式,至少用了django之后是这样;第三种优点是可以用admin系统或模板系统来,缺点是定时任务不熟悉。但考虑到打算深入学习django,于是决定用第三种方式来实现。
Django的定时任务基本也有三种实现形式:
django-celery
django-crontab
首先,看了下django-celery
的官方教程,celery
还是比较庞大的,而且教程比较复杂,没耐心的我就先行跳过了;
其次,又看了Django关于command的官方文档,实现了command+crontab的形式。但因为是在virtualenv下部署,一直无法实现。即便crontab中已经设置了先进入virtualenv再运行command仍然失败了(crontab中语法是source /home/../bin/activate && python /home/.../manage.py aizhan_visits
)。
最后,选择了第三方库django-crontab
,竟意外的实现了Django在virtualenv下的的定时任务。。
django-crontab安装:pip install django-crontab
django-crontab加入:只需要将django-crontab
加入到settings.py的INSTALLED_APPS
即可。如下代码:
INSTALLED_APPS = (
'django-crontab',
...
)
django-crontab可以定时运行自定义命令和函数两种方式,因为之前尝试用command+crontab时已经实现了自定义command,所以自然而然使用了自定义命令这种形式。
我先参考Django官方文档自定义了一个命令aizhan_5domain_visits
,专门用于抓取爱站流量,并将结果保存在sqlite3数据库中(具体步骤在本文中不赘述了)。
其次,我在settings.py
中加入了django-crontab的命令:
CRONJOBS = [
('47 11 * * *', 'django.core.management.call_command', ['aizhan_5domain_visits']),
]
意思就是每天11点47分运行aizhan_5domain_visits
这个命令。接下来就剩最后一步任务加载了。
django-crontab也可以定时运行函数,只是在CRONJOBS
配置时有差别。CRONJOBS
关于函数的配置如下:
CRONJOBS = (
# 初级模式
('*/5 * * * *', 'myproject.myapp.cron.my_scheduled_job'),
# 中级模式
('0 0 1 * *', 'myproject.myapp.cron.my_scheduled_job', '> /tmp/last_scheduled_job.log'),
#高级模式
('0 0 * * 0', 'django.core.management.call_command', ['dumpdata', 'auth'], {'indent': 4}, '> /home/john/backups/last_sunday_auth_backup.json'),
)
分析结果:
my_scheduled_job
这个程序;my_scheduled_job
的结果输出到文件/tmp/last_scheduled_job.log
中;['dumpdata', 'auth']
和{'indent': 4}
都是参数,只是[]
中的参数是按照顺序代入,而{}
中的参数指定了变量名称,最后一个也是输出结果的后缀。 django-crontab任务加载比较简单,只需要运行python manage.py crontab add
即可。如果你运行crontab -e
可以看到crontab中多了一行:
* * * /home/aizhan/bin/python /home/aizhan/aizhan/manage.py crontab run c27d1050fb7f87225bcff587ef5a35a3 # django-cronjobs for aizhan
这是django-crontab自动生成的。
python manage.py crontab remove
;python manage.py crontab add
。 最后通过配置admin.py
,在admin后台实现了基本的数据展现,效果图如下: