1. 程式人生 > >Django-crontab實現定時任務

Django-crontab實現定時任務

1. 前言

為了做一些報表,最近需要每日從愛站上抓取競爭對手的百度流量和移動流量,從我能實現的技術來看,大致有三種實現形式:

  1. 火車頭定時抓取
  2. python+crontab定時抓取,儲存在txt或cav或資料庫中;
  3. django定時任務,用admin系統或模板系統展現。

第一種不熟悉,還要摸索;第二種資料展現還要自己寫,如果用資料庫,還要用很原始的連線方式,至少用了django之後是這樣;第三種優點是可以用admin系統或模板系統來,缺點是定時任務不熟悉。但考慮到打算深入學習django,於是決定用第三種方式來實現。

2. Django定時任務

Django的定時任務基本也有三種實現形式:

  1. django-celery
  2. Django的command+crontab
  3. 一些第三方庫,如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下的的定時任務。。

3. django-crontab實現Django在virtualenv的定時任務

3.1 django-crontab安裝

  • django-crontab安裝
    pip install django-crontab

  • django-crontab加入:只需要將django-crontab加入到settings.py的INSTALLED_APPS即可。如下程式碼:

    1. INSTALLED_APPS =(
    2. 'django-crontab'
      ,
    3. ...
    4. )

3.2 django-crontab配置

django-crontab可以定時執行自定義命令和函式兩種方式,因為之前嘗試用command+crontab時已經實現了自定義command,所以自然而然使用了自定義命令這種形式。

3.2.1 django-crontab定時執行命令

我先參考Django官方文件自定義了一個命令aizhan_5domain_visits,專門用於抓取愛站流量,並將結果儲存在sqlite3資料庫中(具體步驟在本文中不贅述了)。

其次,我在settings.py中加入了django-crontab的命令:

  1. CRONJOBS =[
  2. ('47 11 * * *','django.core.management.call_command',['aizhan_5domain_visits']),
  3. ]

意思就是每天11點47分執行aizhan_5domain_visits這個命令。接下來就剩最後一步任務載入了。

3.2.2 django-crontab定時執行函式

django-crontab也可以定時執行函式,只是在CRONJOBS配置時有差別。CRONJOBS關於函式的配置如下:

  1. CRONJOBS =(
  2. # 初級模式
  3. ('*/5 * * * *','myproject.myapp.cron.my_scheduled_job'),
  4. # 中級模式
  5. ('0 0 1 * *','myproject.myapp.cron.my_scheduled_job','> /tmp/last_scheduled_job.log'),
  6. #高階模式
  7. ('0 0 * * 0','django.core.management.call_command',['dumpdata','auth'],{'indent':4},'> /home/john/backups/last_sunday_auth_backup.json'),
  8. )

分析結果:

  • 初級模式很直觀,意思就是每五分鐘執行一次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後臺實現了基本的資料展現,效果圖如下:

SEO監控系統後臺截圖

參考文件

  • 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

後記

  1. 關於題圖。轉自Sticky Notes的Savage Chickens系列,作者是Doug Savage,本圖名字是Time After Time Cartoon;
  2. 關於感受。長時間不寫,感覺思路不清晰,寫出來的話也毫無生氣。