【问题标题】:How to define a view function in views.py file in django如何在django的views.py文件中定义视图函数
【发布时间】:2016-03-26 17:43:39
【问题描述】:

我想在views.py文件中创建一个视图函数,它在特定的时间间隔内运行,而不依赖于请求对象,这在django中是可能的 我正在做一个使用 bs4、request 和 django 抓取网络数据的简单项目,到目前为止,我能够抓取数据并将其呈现给我的 django views.py。

从不同网站抓取的数据遵循以下格式

news_title = 'were-these-remote-wild-islands'
news_url = 'http://bbc.co.uk/travel/see-the-dark-side-of-climate-change'

我的视图函数有以下代码行

from .bbc import bbc_crawler
from .models import News

def collect_data(request):
    '''
    aggregrate all the news from each
    news portal
    '''


    allnews = []
    #return dict obj {'title':'climate change', 'url':'http://bbc.co.uk'}, {'title':'t', 'url':'http://url.com'}
    allnews.append(bbc_crawler()) 

    for news in allnews:
        for eachnews,link in news.items():
            #Problem is for every request the same data pushed to the database, need a solution to push the data after every 5 minutes, without depending on this function

            News.objects.create(title=eachnews, url=link, source=source)

    return render(request, 'news/index.html', {'allnews':allnews, 'source': source})

上面代码的问题是,上面的视图函数只有在我们访问指向这个 urls.py 文件中定义的视图函数的 url 时才会运行

urls.py

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.news, name="index"),
]

当我刷新该 url 时,每次相同的重复数据都会存储在数据库中。

我想要每5分钟运行一次爬虫并将爬取的数据保存到数据库中的解决方案。

在views.py文件的哪里运行爬虫,这样我可以每5分钟保存一次数据,不重复数据,不依赖于请求对象。我想每5分钟将爬取的数据保存在django数据库中,

如何做到这一点,目前的问题是只有在我们刷新或请求页面时才保存数据。

我不依赖数据库中的请求对象来保存数据

【问题讨论】:

  • 配置一个 celery 任务,从视图中调用它,然后在那里重复。
  • 好的,我会尝试这样做

标签: python django django-models web-scraping django-views


【解决方案1】:

首先我希望你重新考虑你的设计

查看是为了响应用户的请求。不用于抓取数据,您应该实现另一个独立于视图的功能。您的视图应该只显示数据库中的最后一个条目。它不应该抓取数据。

考虑一个场景: 假设我们解决了您的及时执行问题,用户 1 发送一个 GET 请求,它将在 00:01 滴答时抓取数据并将其保存到数据库中。下一个动作应该在 00:06 滴答。现在,如果在 User2 和 User3 之间的时间为 00:02 和 00:03 并且他们发送 GET 请求,新的抓取数据将被添加到数据库中。您应该在 00:01 到 00:06 之间有 2 个条目,但由于 User2 和 3 个有 4 个条目。

所以就这样做吧。这个比较合适

1.在您的应用程序目录中创建一个 myfun.py:

from .bbc import bbc_crawler
from .models import News

 def crawl_data():
  allnews = []
  allnews.append(bbc_crawler()) 
  for news in allnews:
   for eachnews,link in news.items():
    News.objects.create(title=eachnews, url=link, source=source)

2.在启动你的网络服务器之后,只运行一次 crawling.py

 python crawling.py

编写 crawling.py 如下:

import time
from myfun import crawl_data
while(True):
 time.sleep(300)
 crawl_data()         

在您的视图中,只需向任意数量的用户显示数据库中的最后一个条目:

def collect_data(request);
 lastentry=News.objects.all().last()
 allnews=lastentry.allnews #Fetch acoording to your model fields 
 source=lastentry.source   #Fetch acoording to your model fields 
 return render(request, 'news/index.html', {'allnews':allnews, 'source': source})

【讨论】:

    【解决方案2】:

    视图用于响应请求。如果您需要定期进行一些抓取,您应该按照@Rohit Jain 的建议配置一个 celery 任务 - 或者对于琐碎的东西 - 在从 cron 或 supervisor 调用的管理命令中,保存在数据库中抓取的数据,然后从查看。

    【讨论】:

      猜你喜欢
      • 2018-08-20
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2018-02-21
      • 2019-04-07
      相关资源
      最近更新 更多