String formatting kann viel sauberer machen Dinge, und weniger Fehler -anfällig.
Einfaches Beispiel wird %s
durch a title
ersetzt:
my_html = "<html><body><h1>%s</h1></body></html>" % ("a title")
oder mehrere Male (Titel ist das gleiche, und jetzt "mein Inhalt" angezeigt wird, wo die zweite %s
ist:
my_html = "<html><body><h1>%s</h1>%s</body></html>" % ("a title", "my content")
Sie können auch benannte Schlüssel verwenden, wenn Sie %s
, wie %(thekey)s
tun, was bedeutet, dass Sie nicht verfolgen müssen, in welcher Reihenfolge die sind. Anstelle von list, verwenden Sie einen dictionary, die den Schlüssel zu einem Wert abbildet:
my_html = "<html><body><h1>%(title)s</h1>%(content)s</body></html>" % {
"title": "a title",
"content":"my content"
}
Das größte Problem mit dem Skript ist, können Sie eine globale Variable verwenden (data
). Ein viel bessere Weg wäre:
- Aufruf search_results, mit dem Argument „swineflu“
- search_results gibt eine Liste der Ergebnisse, speichern das Ergebnis in einer Variablen
- Anruf WebOutput, mit der Suche Ergebnisse Variable als Argument
- WebOutput einen String zurückgibt, Ihre HTML
- schreiben die zurückgegebene HTML-Dateien enthalten
WebOutput würde den HTML-Code (als String) zurückgeben und in eine Datei schreiben. Etwas wie:
Schließlich ist das twitterd Modul nur erforderlich, wenn Sie auf Daten zugreifen, die eine Anmeldung erfordern. Die öffentliche Zeitleiste ist öffentlich und kann ohne Authentifizierung aufgerufen werden, sodass Sie den twitterd-Import und die Zeile api =
entfernen können.Wenn Sie twitterd verwenden wollten, würden Sie etwas mit dem api
Variable, zum Beispiel zu tun haben:
api = twitterd.Api(username='username', password='password')
statuses = api.GetPublicTimeline()
Also, ich die Art, wie das Drehbuch geschrieben haben könnte, ist:
import time
import urllib
import simplejson
def search_results(query, rpp = 25): # 25 is default value for rpp
url = "http://search.twitter.com/search.json?q=%s&%s" % (query, rpp)
jsonResults = simplejson.load(urllib.urlopen(url))
data = [] # setup empty list, within function scope
for tweet in jsonResults["results"]:
# Unicode!
# And tweet is a dict, so we can use the string-formmating key thing
data.append(u"%(from_user)s | %(text)s" % tweet)
return data # instead of modifying the global data!
def web_output(data, query):
results_html = ""
# loop over each index of data, storing the item in "result"
for result in data:
# append to string
results_html += " <p style='font-size:90%%'>%s</p>\n" % (result)
html = """<html>
<head>
<meta http-equiv='refresh' content='60'>
<title>python newb's twitter search</title>
</head>
<body>
<h1 style='font-size:150%%'>Python Newb's Twitter Search</h1>
<h2 style='font-size:125%%'>Searching Twitter for: %(query)s</h2>
<h2 style='font-size:125%%'> %(ctime)s (updates every 60 seconds)</h2>
%(results_html)s
</body>
</html>
""" % {
'query': query,
'ctime': time.ctime(),
'results_html': results_html
}
return html
def main():
query_string = "swineflu"
results = search_results(query_string) # second value defaults to 25
html = web_output(results, query_string)
# Moved the file writing stuff to main, so WebOutput is reusable
f = open("outw.html", "w")
f.write(html)
f.close()
# Once the file is written, display the output to the terminal:
for formatted_tweet in results:
# the .encode() turns the unicode string into an ASCII one, ignoring
# characters it cannot display correctly
print formatted_tweet.encode('ascii', 'ignore')
if __name__ == '__main__':
main()
# Common Python idiom, only runs main if directly run (not imported).
# Then means you can do..
# import myscript
# myscript.search_results("#python")
# without your "main" function being run
(2) An welchem Punkt wäre ein Framework für eine App wie diese geeignet? Overkill?
würde ich sagen, immer einen Web-Framework verwenden (mit wenigen Ausnahmen)
Nun seltsam, das könnte scheinen, alle Zeit, die ich Korrekturen an das Skript nur ausgegeben gegeben erklären .. aber mit der oben Änderungen an Ihrem Skript, es ist unglaublich einfach zu tun, da alles schön funktionierte!
Mit CherryPy, einem wirklich einfachen HTTP-Framework für Python, können Sie Daten einfach an den Browser senden, anstatt ständig eine Datei zu schreiben.
Dies setzt voraus, dass das obige Skript als twitter_searcher.py
gespeichert wird.
Hinweis Ich habe CherryPy noch nie zuvor verwendet, dies ist nur das HelloWorld-Beispiel auf der CherryPy-Homepage, mit ein paar Zeilen, die aus der obigen main() -Funktion des Skripts kopiert wurden!
import cherrypy
# import the twitter_searcher.py script
import twitter_searcher
# you can now call the the functions in that script, for example:
# twitter_searcher.search_results("something")
class TwitterSearcher(object):
def index(self):
query_string = "swineflu"
results = twitter_searcher.search_results(query_string) # second value defaults to 25
html = twitter_searcher.web_output(results, query_string)
return html
index.exposed = True
cherrypy.quickstart(TwitterSearcher())
speichern und das Skript ausführen, wechseln Sie dann zu http://0.0.0.0:8080/
und es wird Ihre Seite zeigen!
Das Problem damit, auf jeder Seite laden wird es die Twitter API abfragen. Dies wird kein Problem sein, wenn Sie es nur verwenden, aber mit Hunderten (oder sogar Zehner) von Leuten, die die Seite betrachten, würde es langsamer werden (und Sie könnten schließlich durch die Twitter-API eingeschränkt/blockiert werden))
Die Lösung ist im Grunde zurück zum Anfang .. Sie würden das Suchergebnis auf Disc schreiben (Cache) und twittern, wenn die Daten mehr als ~ 60 Sekunden alt sind. Du könntest auch in CherryPy's caching options schauen .. aber diese Antwort wird ziemlich absurd lang ..
Thx alle (llimllib, THC4k, dbr, Buddy)! Ich sehe definitiv den Nutzen eines Frameworks auch für ein kleines Projekt. Ich werde mir die verschiedenen Optionen ansehen und sehen, welche mir am besten gefällt. llimllib: danke für das sehr klare Beispiel. Das war sehr hilfreich! dbr: großes thx !! viel mehr als ich erwartet hatte. (1) sorry über die api referenz, es war nur alte code ich habe vergessen zu löschen. (2) liebe die Umschreibungen/Korrekturen - viel besser und werde diesen Ansatz in meinem gesamten Code verwenden. (3) In einige Unicode-Probleme mit Ihrem Code zu kommen - nicht sicher warum, aber einige Nachforschungen anstellen. – timepilot