2012-06-20 14 views
8

Pracuję nad małym projektem w Pythonie. Jest podzielony na dwie części.Python - Flask - otwórz stronę w domyślnej przeglądarce

Pierwsza część jest odpowiedzialna za zaindeksowanie sieci i wyodrębnienie informacji oraz wstawienie ich do bazy danych.

Druga część jest odpowiedzialna za przedstawienie tych informacji przy użyciu bazy danych. Obie części współdzielą bazę danych. W drugiej części używam struktury Flask do wyświetlania informacji jako html z pewnym formatowaniem, stylem i itp., Aby wyglądał czystszy.

Pliki źródłowe obu części są w tym samym opakowaniu, ale by uruchomić ten program prawidłowo użytkownik musi uruchomić robota i wyniki prezenter oddzielnie tak:

pyton crawler.py

a następnie

pyton presenter.py

Wszystko jest w porządku tylko z wyjątkiem jednej rzeczy. Co mogę zrobić, to utworzyć wynik w formacie HTML i otworzyć stronę z wynikami w domyślnej przeglądarce użytkownika, ale jest ona zawsze otwierana dwa razy, prawdopodobnie z powodu obecności metody run(), która uruchamia Flask w nowym wątku i dla mnie robi się pochmurno. Nie wiem, co powinienem zrobić, aby mój presenter.py mógł otworzyć tylko jedną kartę/okno po uruchomieniu.

Oto fragment mojego kodu:

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

Odpowiedz

17

używam podobnego kodu w systemie Mac OS X (z Safari, Firefox i Chrome) przeglądarek cały czas, i to działa dobrze. Zgaduję, że możesz uruchomić funkcję automatycznego przeładowania Flask. Ustaw debug=False i nie będzie próbował automatycznie przeładować.

Inne propozycje, oparte na moim doświadczeniu:

  • rozważyć losowanie portu używanego, jako szybkie edit prowadzony test pętli czasami znaleźć OS myślenia Port 5000 jest nadal w użyciu. (Lub, jeśli uruchomisz kod kilka razy jednocześnie, powiedzmy przypadkiem, port naprawdę jest nadal używany.)
  • Daj aplikacji na chwilę, aby się zakręcić, zanim uruchomisz żądanie przeglądarki. Robię to poprzez wywołanie threading.Timer.

Oto mój kod:

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) 

(To wszystko jest pod if __name__ == '__main__': lub w oddzielnej funkcji "start aplikacji", jeśli chcesz.)

+0

Dzięki to był pomocny. Właściwie to właśnie ustawienie debugowania na False działało ... i spędziłem na tym tyle czasu .. :) – koleS

+2

Dobrze. 'debug = False' zapobiega duplikowaniu okien przeglądarki. Randomizowany port i opóźnione otwarcie służą do naprawiania innych gier, które widziałem w różnych sytuacjach. –

+1

Problem "dwóch okien broswer" można również obsłużyć (pozostawiając 'debug = True'), sprawdzając zmienne środowiskowe. Po ponownym załadowaniu skryptu przez zmianę, przeładowana instancja ma ustawioną zmienną środowiskową "WERKZEUG_RUN_MAIN". Więc coś takiego: 'if 'WERKZEUG_RUN_MAIN' nie jest w os.environ: threading.Timer (BROWSER_DELAY, lambda: webbrowser.open (APP_URL)).start() 'będzie (aktualnie przynajmniej) uruchamia przeglądarkę tylko raz, niezależnie od ustawienia debugowania aplikacji skrzynki. – jedwards

Powiązane problemy