2016-11-17 78 views
2

嗨stackoverflow社區,我有一個安排cron作業的問題,需要將網站抓取並將其作爲模型(MOVIE)的一部分存儲在數據庫中。問題是模型似乎在執行Procfile之前加載。我應該如何創建一個在後臺內部運行的cron作業,並將刮取的信息存儲到數據庫中?這裏是我的代碼:問題在Django項目中使用apscheduler定義Procfile(Heroku)中的Cron作業

Procfile:

web: python manage.py runserver 0.0.0.0:$PORT 
    scheduler: python cinemas/scheduler.py 

scheduler.py:

# More code above 
from cinemas.models import Movie 
from apscheduler.schedulers.blocking import BlockingScheduler 
sched = BlockingScheduler() 

@sched.scheduled_job('cron', day_of_week='mon-fri', hour=0, minutes=26)  
def get_movies_playing_now(): 
    global url_movies_playing_now 
    Movie.objects.all().delete() 
    while(url_movies_playing_now): 
    title = [] 
    description = [] 
    #Create BeatifulSoup Object with url link 
    s = requests.get(url_movies_playing_now, headers=headers) 
    soup = bs4.BeautifulSoup(s.text, "html.parser") 
    movies = soup.find_all('ul', class_='w462')[0] 

    #Find Movie's title 
    for movie_title in movies.find_all('h3'): 
     title.append(movie_title.text) 
    #Find Movie's description 
    for movie_description in soup.find_all('ul', 
              class_='w462')[0].find_all('p'): 
     description.append(movie_description.text.replace(" [More]",".")) 

    for t, d in zip(title, description): 
     m = Movie(movie_title=t, movie_description=d) 
     m.save() 

    #Go to the next page to find more movies 
    paging = soup.find(class_='pagenating').find_all('a', class_=lambda x: 
                 x != "inactive") 
    href = "" 
    for p in paging: 
     if "next" in p.text.lower(): 
      href = p['href'] 
    url_movies_playing_now = href 

sched.start() 
# More code below 

from django.db import models 

電影院/ models.py:

#Create your models here. 

class Movie(models.Model): 
    movie_title = models.CharField(max_length=200) 
    movie_description = models.CharField(max_length=20200) 

這是我收到的時候錯誤工作正在運行。

2016-11-17T17:57:06.074914 + 00:00 app [scheduler.1]:回溯(最近一次通話最後): 2016-11-17T17:57:06.074931 + 00:00 app [scheduler。 1]:文件「cinemas/scheduler.py」,第2行,在 2016-11-17T17:57:06.075058 + 00:00 app [scheduler.1]:import cineplex 2016-11-17T17:57:06.075060+ 00:00 app [scheduler.1]:文件「/app/cinemas/cineplex.py」,第1行,在 2016-11-17T17:57:06.075173 + 00:00 app [scheduler.1]:from cinemas。模型導入電影 2016-11-17T17:57:06.075196 + 00:00 app [scheduler.1]:文件「/app/cinemas/models.py」,第5行,在 2016-11-17T17:57:06.075295 +00:00 app [scheduler.1]:class Movie(models.Model): 2016-11-17T17:57:06.075297 + 00:00 app [scheduler.1]:File「 /app/.heroku/python/lib/python3.5/site-packages/django/db/models/base.py「,第105行, 2016-11-17T17:57:06.075414 + 00:00 app [scheduler.1]:app_config = apps.get_containing_app_config(module) 2016-11-17T17:57:06.075440 + 00:00 app [scheduler.1]:File「/app/.heroku/python/lib/python3。 5/site-packages/django/apps/registry.py「,第237行,在get_containing_app_config中 2016-11-17T17:57:06.075585 + 00:00 app [scheduler.1]:self.check_apps_ready() 2016-11 -17T17:57:06.075586 + 00:00 app [scheduler.1]:文件「/app/.heroku/python/lib/python3.5/site-packages/django/apps/registry.py」,第124行,在check_apps_ready 2016-11-17T17:57:06.075703 + 00:00 app [scheduler.1]:raise AppRegistryNotReady(「Apps are not loaded yet。」) 2016-11-17T17:57:06.075726 + 00:00 app [SCH eduler.1]:django.core.exceptions.AppRegistryNotReady:應用尚未加載。

如果我不包含模型對象,Cron作業正常工作。我應該如何使用Model對象每天運行這個工作而不失敗?

謝謝

回答

2

這是因爲你不能只導入Django包,模型等;要正常工作,Django內部需要從manage.py觸發的初始化。我不會嘗試重新創建自己的所有內容,而是始終將長時間運行的非Web命令編寫爲自定義管理命令(請參閱https://docs.djangoproject.com/en/1.10/howto/custom-management-commands/)。例如,如果您的應用程序爲cinemas,那麼您應該:

  • 創建./cinemas/management/commands/scheduler.py
  • 在該文件中,子類django.core.management.base.BaseCommand(該子類必須叫作Command
  • 在這個類,覆蓋handle()。在你的情況,這就是你會打電話sched.start()
  • Procfile將不得不scheduler: python manage.py scheduler

希望有所幫助。

+0

謝謝!這對我有用:) –

0

可以解決添加以下行到sceduler.py

import django 
django.setup() 

的頂部。在Django文檔it says

如果你使用Django的組件「獨立問題「 - 例如,編寫一個加載一些Django模板並渲染它們的Python腳本,或者使用ORM獲取一些數據 - 除了配置設置之外,還需要一步。

在設置了DJANGO_SETTINGS_MODULE或調用configure()之後,您需要調用django.setup()來加載設置並填充Django的應用程序註冊表。例如:

import django 
from django.conf import settings 
from myapp import myapp_defaults 

settings.configure(default_settings=myapp_defaults, DEBUG=True) 
django.setup() 

# Now this script or any imported module can use any part of Django it needs. 
from myapp import models 

我設置DJANGO_SETTINGS_MODULE的配置變量,所以沒有將它添加到我的調度。