Форматирование строк может сделать вещи намного аккуратнее и менее подвержено ошибкам.
Простой пример, %s
заменяется на a title
:
my_html = "<html><body><h1>%s</h1></body></html>" % ("a title")
Или несколько раз (заголовок один и тот же, и теперь отображается «мой контент», где второй %s
:
my_html = "<html><body><h1>%s</h1>%s</body></html>" % ("a title", "my content")
Вы также можете использовать именованные ключи при выполнении %s
, например %(thekey)s
, что означает, что вам не нужно отслеживать, в каком порядке находится %s
. Вместо списка, вы используете словарь , который сопоставляет ключ со значением:
my_html = "<html><body><h1>%(title)s</h1>%(content)s</body></html>" % {
"title": "a title",
"content":"my content"
}
Самая большая проблема в вашем скрипте - вы используете глобальную переменную (data
). A намного лучше было бы:
- call search_results, с аргументом "swineflu"
- search_results возвращает список результатов, сохраните результат в переменной
- вызвать WebOutput с переменной результатов поиска в качестве аргумента
- WebOutput возвращает строку, содержащую ваш HTML
- записать возвращенный HTML в ваш файл
WebOutput возвращает HTML (в виде строки) и записывает его в файл. Что-то вроде:
results = SearchResults("swineflu", 25)
html = WebOutput(results)
f = open("outw.html", "w")
f.write(html)
f.close()
Наконец, модуль twitterd требуется только в том случае, если вы обращаетесь к данным, требующим входа в систему. Общедоступная временная шкала является общедоступной, и к ней можно получить доступ без какой-либо аутентификации, поэтому вы можете удалить импорт из twitterd и строку api =
. Если вы хотите использовать twitterd, вам нужно будет что-то сделать с переменной api
, например:
api = twitterd.Api(username='username', password='password')
statuses = api.GetPublicTimeline()
Итак, я мог бы написать сценарий так:
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) в какой момент среда подойдет для такого приложения, как это? излишество?
Я бы сказал, всегда используйте веб-фреймворк (за некоторыми исключениями)
Теперь, это может показаться странным, учитывая все время, которое я потратил на объяснение исправлений в вашем скрипте ... но, с учетом вышеописанных модификаций вашего скрипта, это невероятно легко сделать, так как все было хорошо функционально модифицировано!
Используя CherryPy , который является действительно простой платформой HTTP для Python, вы можете легко отправлять данные в браузер, вместо того, чтобы постоянно записывать файл.
Предполагается, что вышеуказанный скрипт сохранен как twitter_searcher.py
.
Примечание. Я никогда раньше не использовал CherryPy, это всего лишь пример HelloWorld на домашней странице CherryPy с несколькими строками, скопированными из функции main () вышеприведенного скрипта!
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())
Сохраните и запустите этот скрипт, затем перейдите к http://0.0.0.0:8080/
, и он покажет вашу страницу!
Проблема с этим, при каждой загрузке страницы он будет запрашивать API Twitter. Это не будет проблемой, если только вы используете его, но когда сотни (или даже десятки) людей смотрят на страницу, она начнет замедляться (и вы можете получить ограничение / блокировку по скорости с помощью Twitter API, в конце концов). )
Решение в основном вернулось к началу. Вы должны записать (кэшировать) результаты поиска на диск, повторно выполнив поиск в Твиттере, если данные старше 60 секунд. Вы также можете взглянуть на опции кэширования CherryPy .. но этот ответ становится довольно нелепо длинным ..