简体   繁体   English

无限运行 Flask 应用程序

[英]Running a Flask application infinitely

I am running a simple website which shows the current price of silver.我正在运行一个显示当前白银价格的简单网站。 How do I make it run in an infinite loop, so that it keeps updating the price after scraping it from silverseek.com after any interval(10secs for eg? I tried working with BackgroundScheduler, however, it throws an error我如何让它在无限循环中运行,以便在任何时间间隔(例如 10 秒?我尝试使用 BackgroundScheduler,但是,它会引发错误

Execution of job "silver (trigger: interval[0:00:10], next run at: 2020-01-08 17:56:27 IST)" skipped: maximum number of running instances reached (1) Job "silver (trigger: interval[0:00:10], next run at: 2020-01-08 17:56:37 IST)" raised an exception Traceback (most recent call last): File "C:\\Users\\Abhi\\PycharmProjects\\Cricket\\venv\\lib\\site-packages\\apscheduler\\executors\\base.py", line 125, in run_job retval = job.func(*job.args, **job.kwargs) File "C:/Users/Abhi/PycharmProjects/Cricket/internet.py", line 25, in silver return render_template('home.html', s=txt.get_text()) File "C:\\Users\\Abhi\\PycharmProjects\\Cricket\\venv\\lib\\site-packages\\flask\\templating.py", line 136, in render_template ctx.app.update_template_context(context) AttributeError: 'NoneType' object has no attribute 'app'跳过作业“silver (trigger: interval[0:00:10], next run at: 2020-01-08 17:56:27 IST)”:已达到最大运行实例数 (1) 作业“silver (trigger)” : interval[0:00:10], next run at: 2020-01-08 17:56:37 IST)”引发异常回溯(最近一次调用):文件“C:\\Users\\Abhi\\PycharmProjects\\Cricket \\venv\\lib\\site-packages\\apscheduler\\executors\\base.py”,第 125 行,在 run_job retval = job.func(*job.args, **job.kwargs) 文件“C:/Users/Abhi/PycharmProjects /Cricket/internet.py", line 25, in silver return render_template('home.html', s=txt.get_text()) File "C:\\Users\\Abhi\\PycharmProjects\\Cricket\\venv\\lib\\site-packages \\flask\\templating.py",第 136 行,在 render_template ctx.app.update_template_context(context) AttributeError: 'NoneType' 对象没有属性 'app'

Here is the code.这是代码。

from bs4 import BeautifulSoup
from selenium import webdriver
import time
from apscheduler.schedulers.background import BackgroundScheduler
from flask import Flask, render_template




app = Flask(__name__)


@app.route('/')
def silver():
    url = "http://silverseek.com/"
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--headless')
    driver = webdriver.Chrome(executable_path='C:/Users/Rags/Downloads/cd79/chromedriver.exe', options=chrome_options)
    driver.get(url)
    time.sleep(8)
    sil = driver.page_source
    bs = BeautifulSoup(sil, "lxml")
    elem = bs.find_all('div', class_='quote-container')
    for txt in elem:
        return render_template('home.html', s=txt.get_text())


sched = BackgroundScheduler(daemon=True)
sched.add_job(silver, 'interval', seconds=10)
sched.start()

if __name__ == "__main__":
    app.run()

You mean that you hope the page content to automagically refresh in your browser ?您的意思是希望页面内容在浏览器中自动刷新? – bruno desthuilliers 19 mins ago – 布鲁诺 desthuilliers 19 分钟前
@brunodesthuilliers Yes, that was the idea..I hope I am not entirely wrong in some way. @brunodesthuilliers 是的,就是这个想法..我希望我在某种程度上没有完全错。

Mmm... That's what I suspected - and that's not how it works at all.嗯……这就是我所怀疑的 - 而它根本不是这样工作的。 The HTTP protocol is based on a request / response cycle - the client send a request (to GET a given url, or POST some data at a given URL etc), the request is routed to the server, the server returns a response (with the status code, content and headers), AND THE CYCLE IS OVER. HTTP 协议基于请求/响应周期 - 客户端发送请求(获取给定的 url,或在给定的 URL 上 POST 一些数据等),请求被路由到服务器,服务器返回响应(带有状态代码、内容和标题),并且周期结束。 The server doesn't keep any connection to the client once the response has been sent.发送响应后,服务器不会与客户端保持任何连接。

Actually, your app IS already "running forever" - that's what the app.run() calls do - waiting for requests to come in. Each time you send a request (each time you load the page in your browser for example), your silver() function is called and the result is returned as a HTTP response (flask takes care of wrapping it in a proper response if necessary).实际上,您的应用程序已经“永远运行” - 这就是app.run()调用所做的 - 等待请求进来。每次发送请求(例如,每次在浏览器中加载页面时),您的silver()函数被调用,结果作为 HTTP 响应返回(如有必要,flask 负责将其包装在适当的响应中)。 Of course once the browser has rendered the response (displaying your "page"), nothing else happens - the page will not magically refresh itself.当然,一旦浏览器呈现响应(显示您的“页面”),其他任何事情都不会发生 - 页面不会神奇地自行刷新。 But if you manually refresh it (reload the page - F5 key for most browsers), it will send a new request, and you will then get up to date informations.但是,如果您手动刷新它(重新加载页面 - 对于大多数浏览器,F5 键),它将发送一个新请求,然后您将获得最新信息。

If you want your page to keep on refreshing itself, you either have to make the client (in this case your browser) refrehsing it, or use a more elaborate protocol like websockets etc (something that maintains a connection between client and server so the server can push to the client).如果您希望您的页面不断刷新自己,您要么必须让客户端(在这种情况下是您的浏览器)刷新它,或者使用更复杂的协议,如 websockets 等(在客户端和服务器之间保持连接的东西,以便服务器可以推送给客户端)。

For your case, this is certainly overkill, so the simple obvious solution is to use client-side scripting - IOW javascript - to refresh the page every X seconds.对于您的情况,这肯定是矫枉过正,所以简单明显的解决方案是使用客户端脚本 - IOW javascript - 每 X 秒刷新一次页面。 This is trivial and there's no shortage of examples so I won't bother posting one here.这是微不足道的,而且不乏示例,所以我不会费心在这里发布一个。

Now if this is for learning purpose, you may still want to try out the "more elaborate" solution too so you get a first taste of how it works (django has 'django-channels' for this, and there's very certainly something similar for flask), but I reckon you'd be better learning more about HTTP itself first before moving on to those more advanced topics.现在,如果这是出于学习目的,您可能仍然想尝试“更精细”的解决方案,以便您初步了解它的工作原理(django 对此有 'django-channels',并且肯定有类似的东西)烧瓶),但我认为你最好先学习更多关于 HTTP 本身的知识,然后再继续那些更高级的主题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM