Django-crontab實現定時任務
1. 前言
為了做一些報表,最近需要每日從愛站上抓取競爭對手的百度流量和移動流量,從我能實現的技術來看,大致有三種實現形式:
- 火車頭定時抓取;
- python+crontab定時抓取,儲存在txt或cav或資料庫中;
- django定時任務,用admin系統或模板系統展現。
第一種不熟悉,還要摸索;第二種資料展現還要自己寫,如果用資料庫,還要用很原始的連線方式,至少用了django之後是這樣;第三種優點是可以用admin系統或模板系統來,缺點是定時任務不熟悉。但考慮到打算深入學習django,於是決定用第三種方式來實現。
2. Django定時任務
Django的定時任務基本也有三種實現形式:
django-celery
- Django的command+crontab
- 一些第三方庫,如
django-crontab
首先,看了下django-celery
的官方教程,celery
還是比較龐大的,而且教程比較複雜,沒耐心的我就先行跳過了;
其次,又看了Django關於command的官方文件,實現了command+crontab的形式。但因為是在virtualenv下部署,一直無法實現。即便crontab中已經設定了先進入virtualenv再執行command仍然失敗了(crontab中語法是source /home/../bin/activate && python /home/.../
)。
最後,選擇了第三方庫django-crontab
,竟意外的實現了Django在virtualenv下的的定時任務。。
3. django-crontab實現Django在virtualenv的定時任務
3.1 django-crontab安裝
-
django-crontab安裝:
pip install django-crontab
-
django-crontab加入:只需要將
django-crontab
加入到settings.py的INSTALLED_APPS
即可。如下程式碼:- INSTALLED_APPS =(
- 'django-crontab'
- ...
- )
3.2 django-crontab配置
django-crontab可以定時執行自定義命令和函式兩種方式,因為之前嘗試用command+crontab時已經實現了自定義command,所以自然而然使用了自定義命令這種形式。
3.2.1 django-crontab定時執行命令
我先參考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
這個命令。接下來就剩最後一步任務載入了。
3.2.2 django-crontab定時執行函式
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}
都是引數,只是[]
中的引數是按照順序代入,而{}
中的引數指定了變數名稱,最後一個也是輸出結果的字尾。
3.3 django-crontab任務載入
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
。
4. 實現效果
最後通過配置admin.py
,在admin後臺實現了基本的資料展現,效果圖如下:
參考文件
- django-celery的官方文件:http://docs.celeryproject.org/en/latest/getting-started/first-steps-with-celery.html
- django-crontab的官方文件:https://github.com/kraiz/django-crontab
- Django官方文件中關於自定義command的部分:https://docs.djangoproject.com/en/1.6/howto/custom-management-commands/
- 關於crontab任務的說明:http://www.flatws.cn/article/program/shell/2011-02-23/14037.html
後記
- 關於題圖。轉自Sticky Notes的Savage Chickens系列,作者是Doug Savage,本圖名字是Time After Time Cartoon;
- 關於感受。長時間不寫,感覺思路不清晰,寫出來的話也毫無生氣。