Estoy trabajando en un pequeño proyecto en Python. Está dividido en dos partes.Python - Flask - abrir una página web en el navegador predeterminado
La primera parte es responsable de rastrear la web y extraer información e insertarla en una base de datos.
La segunda parte es responsable de presentar esa información con el uso de la base de datos. Ambas partes comparten la base de datos. En la segunda parte, estoy usando Flask framework para mostrar información como html con algunos formatos, estilos, etc. para que se vea más limpio.
Los archivos de origen de ambas partes están en el mismo paquete, pero para ejecutar este programa adecuadamente usuario tiene que ejecutar orugas y resulta presentador separado de esta manera:
pitón crawler.py
y luego
pitón presenter.py
Todo es simplemente allright, excepto una cosa. Lo que hago para presentar es el resultado en formato html y abrir la página con los resultados en el navegador predeterminado del usuario, pero siempre se abre dos veces, probablemente debido a la presencia del método run(), que inicia Flask en un nuevo hilo y las cosas se nublan para mí. No sé qué debería hacer para poder hacer que mi presentador.py abra solo una pestaña/ventana después de ejecutarlo.
Aquí es el fragmento de mi código:
from flask import Flask, render_template
import os
import sqlite3
# configuration
DEBUG = True
DATABASE = os.getcwd() + '/database/database.db'
app = Flask(__name__)
app.config.from_object(__name__)
app.config.from_envvar('CRAWLER_SETTINGS', silent=True)
def connect_db():
"""Returns a new connection to the database."""
try:
conn = sqlite3.connect(app.config['DATABASE'])
return conn
except sqlite3.Error:
print 'Unable to connect to the database'
return False
@app.route('/')
def show_entries():
u"""Loads pages information and emails from the database and
inserts results into show_entires template. If there is a database
problem returns error page.
"""
conn = connect_db()
if conn:
try:
cur = connect_db().cursor()
results = cur.execute('SELECT url, title, doctype, pagesize FROM pages')
pages = [dict(url=row[0], title=row[1].encode('utf-8'), pageType=row[2], pageSize=row[3]) for row in results.fetchall()]
results = cur.execute('SELECT url, email from emails')
emails = {}
for row in results.fetchall():
emails.setdefault(row[0], []).append(row[1])
return render_template('show_entries.html', pages=pages, emails=emails)
except sqlite3.Error, e:
print ' Exception message %s ' % e
print 'Could not load data from the database!'
return render_template('show_error_page.html')
else:
return render_template('show_error_page.html')
if __name__ == '__main__':
url = 'http://127.0.0.1:5000'
webbrowser.open_new(url)
app.run()
Gracias esto era útil. En realidad, bastaba con configurar la depuración en False ... y lo pasé tanto tiempo ... :) – koleS
Derecha. 'debug = False' evita las ventanas duplicadas del navegador. El puerto aleatorizado y el retraso abierto son para corregir otros errores que he visto en diversas situaciones. –
El problema de "dos ventanas de doble hoja" también se puede manejar (dejando 'debug = True') inspeccionando las variables de entorno. Cuando el script se vuelve a cargar a través de un cambio, la instancia recargada tiene configurada la variable de entorno 'WERKZEUG_RUN_MAIN'. Así que algo como: 'si 'WERKZEUG_RUN_MAIN' no está en os.environ: threading.Timer (BROWSER_DELAY, lambda: webbrowser.open (APP_URL)).start() 'lanzará (actualmente, al menos) el navegador una sola vez, independientemente de la configuración de depuración de la aplicación del matraz. – jedwards