2016-11-11 4 views
3

TwitterストリーミングAPIからツイートを読んでいます。 APIに接続した後、私はジェネレータを取得しています。特定の時刻に発電機を終了する方法はありますか?

私は受け取った各ツイートをループしていますが、反復子を18PMで終了したいと考えています。各ツイートを受信した後、指定されたタイムスタンプよりも遅いかどうかを確認しています。

問題は、私が頻繁につぶやきを受け取っていないということです。だから、私は17時50分に1つを受け取ることができ、次の1つを19時に受け取ることができます。それは時間が過ぎたことを知り、私が止める必要がある時です。

18PMで強制停止する方法はありますか?ここで

は、私のコードの高レベルのビューです:

def getStream(tweet_iter): 
    for tweet in tweet_iter: 
     #do stuff 
     if time_has_passed(): 
      return 

tweet_iter = ConnectAndGetStream() 
getStream(tweet_iter) 
+2

注意:PEP 8に従うことをお勧めします( 'getStream'は' get_stream'にする必要がありますが、正式に推奨されています)。 – EOL

+0

スクリプトが6時に正確に実行を停止しない場合、どうして問題になりますか? – jonrsharpe

+2

私はtweet-generatorからの戻り値を動的に取得する時間を推測するので、次の()コールを何時かのタイムアウトでラップして、何時であるかを確認する余地があります。 http://stackoverflow.com/questions/492519/timeout-on-a-function-call – Moberg

答えて

1

あなたの問題は、2つの別々のプロセスにあなたのデザインの機能を分割することによって解決することができます。

  1. として機能さえずりプロセスTwitter APIへのラッパーと
  2. 終了時間に達すると、Twitterプロセスを終了できるモニタープロセス。

次のコードはPythonのマルチプロセッシングモジュールを使用して上記の機能をプロトタイプ:

あなたが代わりに提示しながら、真のループを使用しての p.join(TIMEOUT)を使用することができます。もちろん、
import multiprocessing as mp 
import time 

EXIT_TIME = '12:21' #'18:00' 

def twitter(): 

    while True: 
     print 'Twittttttttttt.....' 
     time.sleep(5) 

def get_time(): 

    return time.ctime().split()[3][:5] 

if __name__ == '__main__': 

    # Execute the function as a process 
    p = mp.Process(target=twitter, args=()) 
    p.start() 

    # Monitoring the process p 
    while True: 
     print 'Checking the hour...' 
     if get_time() == EXIT_TIME: 
      p.terminate() 
      print 'Current time:', time.ctime() 
      print 'twitter process has benn terminated...' 
      break 
     time.sleep(5) 

私の例を指摘したようにhere。ここ

+0

ありがとうございます。あなたのプロトタイプは完璧に動作しているようですが、いくつかの問題に直面しています。私はいくつかの引数を 'twitter'関数に渡しています。その中で、私はロガーオブジェクトを渡し、私はこのエラーメッセージ "TypeError:pickle threadオブジェクトを選ぶことはできません"を得ています。これについて何か知っていますか? – Stergios

+0

次の投稿を確認してください:http://stackoverflow.com/a/7865512/2194843 直面したエラーの種類の回避策が含まれています。 – funk

1

はスレッドとPythonスケジューラとの例である:

import threading 
import time 
import os 
import schedule 

def theKillingJob(): 
    print("Kenny and Cartman die!") 
    os._exit(1) 

schedule.every().day.at("18:00").do(theKillingJob,'It is 18:00') 

def getStream(tweet_iter): 
    for tweet in tweet_iter: 
     #do stuff 

def kenny(): 
    while True: 
     print("Kenny alive..") 
     schedule.run_pending() 
     time.sleep(1) 

def cartman(): 
    while True: 
     print("Cartman alive..") 

     tweet_iter = ConnectAndGetStream() 
     getStream(tweet_iter) 

     # You can change whenever you want to check for tweets by changing sleep time here 
     time.sleep(1) 

if __name__ == '__main__': 
    daemon_kenny = threading.Thread(name='kenny', target=kenny) 
    daemon_cartman = threading.Thread(name='cartman', target=cartman) 
    daemon_kenny.setDaemon(True) 
    daemon_cartman.setDaemon(True) 

    daemon_kenny.start() 
    daemon_cartman.start() 
    daemon_kenny.join() 
    daemon_cartman.join() 
1

生産のために別のスレッドを作成して通信するQueueを使用します。私もプロデューサーを停止するためにthreading.Eventを使用しなければなりませんでした。

import itertools, queue, threading, time 

END_TIME = time.time() + 5 # run for ~5 seconds 

def time_left(): 
    return END_TIME - time.time() 

def ConnectAndGetStream():    # stub for the real thing 
    for i in itertools.count(): 
     time.sleep(1) 
     yield "tweet {}".format(i) 

def producer(tweets_queue, the_end): # producer 
    it = ConnectAndGetStream() 
    while not the_end.is_set(): 
     tweets_queue.put(next(it)) 

def getStream(tweets_queue, the_end): # consumer 
    try: 
     while True: 
      tweet = tweets_queue.get(timeout=time_left()) 
      print('Got', tweet) 
    except queue.Empty: 
     print('THE END') 
     the_end.set() 

tweets_queue = queue.Queue() # you might wanna use the maxsize parameter 
the_end = threading.Event() 
producer_thread = threading.Thread(target=producer, 
            args=(tweets_queue, the_end)) 
producer_thread.start() 
getStream(tweets_queue, the_end) 
producer_thread.join() 
関連する問題