2012-06-20 40 views
8

Tôi đang làm việc trên một dự án nhỏ bằng Python. Nó được chia thành hai phần.Python - Flask - mở một trang web trong trình duyệt mặc định

Phần đầu chịu trách nhiệm thu thập thông tin trên web và trích xuất một số thông tin và chèn chúng vào cơ sở dữ liệu.

Phần thứ hai có khả năng thể hiện thông tin đó khi sử dụng cơ sở dữ liệu. Cả hai phần đều chia sẻ cơ sở dữ liệu. Trong phần thứ hai, tôi đang sử dụng khung Flask để hiển thị thông tin dưới dạng html với một số định dạng, kiểu dáng và vv để làm cho nó trông sạch hơn.

file Source của cả hai bộ phận trong cùng một gói, nhưng để chạy chương trình này đúng người dùng phải chạy bánh xích và kết quả dẫn chương trình riêng như thế này:

python crawler.py

và sau đó

python presenter.py

Mọi thứ đều Allright chỉ trừ một điều. Những gì tôi trình bày để làm là tạo kết quả ở định dạng html và mở trang với kết quả trong trình duyệt mặc định của người dùng, nhưng nó luôn được mở hai lần, có thể do sự hiện diện của phương thức run(), khởi động Flask trong một chuỗi mới và mọi thứ trở nên có mây đối với tôi. Tôi không biết mình nên làm gì để có thể làm cho presenter.py của mình chỉ mở một tab/cửa sổ sau khi chạy nó.

Dưới đây là đoạn mã của tôi:

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

Trả lời

17

tôi sử dụng mã tương tự trên Mac OS X (với Safari, Firefox và các trình duyệt Chrome) tất cả các thời gian, và nó chạy tốt. Đoán bạn có thể đang chạy vào tính năng tự động tải lại của Flask. Đặt debug=False và nó sẽ không cố gắng tự động tải lại.

gợi ý khác, dựa trên kinh nghiệm của tôi:

  • Hãy xem xét ngẫu nhiên các cổng mà bạn sử dụng, như nhanh chóng chỉnh sửa ương kiểm tra loops đôi khi tìm ra OS nghĩ cổng 5000 vẫn được sử dụng. (Hoặc, nếu bạn chạy mã nhiều lần đồng thời, nói một cách tình cờ, cổng thực sự vẫn đang được sử dụng.)
  • Cung cấp cho ứng dụng một thời gian ngắn để quay lên trước khi bạn bắt đầu yêu cầu trình duyệt. Tôi làm điều đó thông qua việc gọi threading.Timer.

Dưới đây là mã của tôi:

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) 

(Đây là tất cả dưới if __name__ == '__main__':, hoặc trong một chức năng riêng biệt "bắt đầu ứng dụng" nếu bạn muốn.)

+0

Cảm ơn này là hữu ích. Trên thực tế chỉ cần thiết lập để gỡ lỗi False làm việc .. và tôi đã dành trên này rất nhiều thời gian .. :) – koleS

+2

Right. 'debug = False' ngăn các cửa sổ trình duyệt trùng lặp. Cổng ngẫu nhiên và trì hoãn mở là để sửa chữa các gotchas khác mà tôi đã thấy trong các tình huống khác nhau. –

+1

Vấn đề "hai cửa sổ broswer" cũng có thể được xử lý (trong khi rời 'debug = True') bằng cách kiểm tra các biến môi trường. Khi kịch bản được tải lại thông qua thay đổi, cá thể được nạp lại có biến môi trường 'WERKZEUG_RUN_MAIN'. Vì vậy, một cái gì đó như: 'if 'WERKZEUG_RUN_MAIN' không có trong os.environ: threading.Timer (BROWSER_DELAY, lambda: webbrowser.open (APP_URL)).start() 'sẽ (hiện tại, ít nhất) khởi động trình duyệt chỉ một lần, bất kể cài đặt gỡ lỗi của ứng dụng bình. – jedwards

Các vấn đề liên quan