python做一个软件里面有浏览器_Python - Flask - 在默认浏览器中打开一个网页

I am working on a small project in Python. It is divided into two parts.

First part is responsible to crawl the web and extract some infromation and insert them into a database.

Second part is resposible for presenting those information with use of the database.

Both parts share the database. In the second part I am using Flask framework to display information as html with some formatting, styling and etc. to make it look cleaner.

Source files of both parts are in the same package, but to run this program properly user has to run crawler and results presenter separately like this :

python crawler.py

and then

python presenter.py

Everything is allright just except one thing. What I what presenter to do is to create result in html format and open the page with results in user's default browser, but it is always opened twice, probably due to the presence of run() method, which starts Flask in a new thread and things get cloudy for me. I don't know what I should do to be able to make my presenter.py to open only one tab/window after running it.

Here is the snippet of my code :

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()

解决方案

I use similar code on Mac OS X (with Safari, Firefox, and Chrome browsers) all the time, and it runs fine. Guessing you may be running into Flask's auto-reload feature. Set debug=False and it will not try to auto-reload.

Other suggestions, based on my experience:

Consider randomizing the port you use, as quick edit-run-test loops sometimes find the OS thinking port 5000 is still in use. (Or, if you run the code several times simultaneously, say by accident, the port truly is still in use.)

Give the app a short while to spin up before you start the browser request. I do that through invoking threading.Timer.

Here's my code:

import random, threading, webbrowser

port = 5000 + random.randint(0, 999)

url = "http://127.0.0.1:{0}".format(port)

threading.Timer(1.25, lambda: webbrowser.open(url) ).start()

app.run(port=port, debug=False)

(This is all under the if __name__ == '__main__':, or in a separate "start app" function if you like.)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值