Мне нужно сохранить в режиме реального времени базу данных всех твитов из Twitter Streaming API, конечно, фильтруя их из определенного списка слов. Я достиг этого, используя tweetstream, определяя такие слова списка, как это, прежде чем вызывать FilterStream():
words = ["word1","two words","anotherWord"]
То, что я хотел бы сделать, - это возможность добавлять/изменять/удалять любые из этих значений, не останавливая сценарий. Для этого я создал простой текстовый файл, содержащий слова, которые я хочу отфильтровать, разделенные разрывом строки. Используя этот код, я получаю только слова списка:
file = open('words.txt','r')
words = file.read().split("\n")
Я делал эти строки работающими, когда они начинаются, но мне нужно, чтобы это делалось каждый раз, когда он собирался проверить поток. Есть идеи?
Вы можете прочитать обновленный список слов в одном потоке и обработать твиты в другом, используя Queue
для связи.
Поток, который читает твиты:
def read_tweets(q):
words = q.get()
while True:
with tweetstream.FilterStream(..track=words,..) as stream:
for tweet in stream: #NOTE:it requires special handling if it blocks
process(tweet)
try: words = q.get_nowait() # try to read a new word list
except Empty: pass
else: break # start new connection
Тема, которая читает слова:
def read_words(q):
words = None
while True:
with open('words.txt') as file:
newwords = file.read().splitlines()
if words != newwords:
q.put(newwords)
words = newwords
time.sleep(1)
Основной сценарий может выглядеть так:
q = Queue(1)
t = Thread(target=read_tweets, args=(q,))
t.daemon = True
t.start()
read_words(q)
Вместо опроса вы можете использовать inotify
или аналогично изменениям монитора в файле 'words.txt'
.
Возможно, что-то вроде этого будет работать:
def rebuild_wordlist(s):
with open('words.txt','r') as f:
return set(f.read().split('\n'))
def match(tweet):
return any(w in tweet for w in words)
words, timestamp = rebuild_wordlist(), time.time()
stream = tweetstream.SampleStream("username", "password")
fstream = ifilter(match, stream)
for tweet in fstream:
do_some_with_tweet(tweet)
if time.time() > timestamp + 5.0:
# refresh the wordlist every 5 seconds
words, timestamp = rebuild_wordlist(), time.time()
Набор слов - это глобальный, который обновляется каждые несколько секунд во время работы фильтра.