2012-04-10 6 views
3

Ich bin neu nicht nur Python, aber Programmierung insgesamt, so würde ich Ihre Hilfe sehr zu schätzen wissen!streaming api mit tweepy gibt nur vorletzten tweet und NICHT die sofort letzte tweet

Ich versuche, alle Tweets von der Twitter-Streaming-API mit Tweepy zu filtern.

Ich habe nach Benutzer-ID gefiltert und haben bestätigt, dass Tweets in Echtzeit gesammelt werden.

JEDOCH, so scheint es, dass nur der vorletzter Tweet Dies ist auf den neuesten Stand tweet im Gegensatz in Echtzeit gesammelt werden.

Können Sie Jungs helfen?

import tweepy 
import webbrowser 
import time 
import sys 

consumer_key = 'xyz' 
consumer_secret = 'zyx' 


## Getting access key and secret 
auth = tweepy.OAuthHandler(consumer_key, consumer_secret) 
auth_url = auth.get_authorization_url() 
print 'From your browser, please click AUTHORIZE APP and then copy the unique PIN: ' 
webbrowser.open(auth_url) 
verifier = raw_input('PIN: ').strip() 
auth.get_access_token(verifier) 
access_key = auth.access_token.key 
access_secret = auth.access_token.secret 


## Authorizing account privileges 
auth.set_access_token(access_key, access_secret) 


## Get the local time 
localtime = time.asctime(time.localtime(time.time())) 


## Status changes 
api = tweepy.API(auth) 
api.update_status('It worked - Current time is %s' % localtime) 
print 'It worked - now go check your status!' 


## Filtering the firehose 
user = [] 
print 'Follow tweets from which user ID?' 
handle = raw_input(">") 
user.append(handle) 

keywords = [] 
print 'What keywords do you want to track? Separate with commas.' 
key = raw_input(">") 
keywords.append(key) 

class CustomStreamListener(tweepy.StreamListener): 

    def on_status(self, status): 

     # We'll simply print some values in a tab-delimited format 
     # suitable for capturing to a flat file but you could opt 
     # store them elsewhere, retweet select statuses, etc. 



     try: 
      print "%s\t%s\t%s\t%s" % (status.text, 
             status.author.screen_name, 
             status.created_at, 
             status.source,) 
     except Exception, e: 
      print >> sys.stderr, 'Encountered Exception:', e 
      pass 

    def on_error(self, status_code): 
     print >> sys.stderr, 'Encountered error with status code:', status_code 
     return True # Don't kill the stream 

    def on_timeout(self): 
     print >> sys.stderr, 'Timeout...' 
     return True # Don't kill the stream 

# Create a streaming API and set a timeout value of ??? seconds. 

streaming_api = tweepy.streaming.Stream(auth, CustomStreamListener(), timeout=None) 

# Optionally filter the statuses you want to track by providing a list 
# of users to "follow". 

print >> sys.stderr, "Filtering public timeline for %s" % keywords 

streaming_api.filter(follow=handle, track=keywords) 

Antwort

5

Ich hatte das gleiche Problem. Die Antwort war nicht so einfach, wie Python ungepuffert in meinem Fall auszuführen, und ich nehme an, dass es das Problem des ursprünglichen Posters auch nicht gelöst hat. Das Problem liegt tatsächlich im Code für das Tweepy-Paket in einer Datei mit dem Namen streaming.py und der Funktion _read_loop(), die meiner Meinung nach aktualisiert werden muss, um Änderungen an dem Format zu berücksichtigen, in dem twitter Daten aus ihrer Streaming-API ausgibt.

Die Lösung für mich war, den neuesten Code für Tweepy von Github, https://github.com/tweepy/tweepy speziell die streaming.py-Datei herunterzuladen. Sie können die kürzlich vorgenommenen Änderungen anzeigen, um zu versuchen, dieses Problem im Commitverlauf für diese Datei zu beheben.

Ich schaute in die Details der Tweepy-Klasse und es gab ein Problem mit der Art, wie die streaming.py-Klasse den JSON-Tweet-Stream einliest. Ich denke, es hat damit zu tun, dass Twitter seine Streaming-API so aktualisiert, dass sie die Anzahl der Bits eines eingehenden Status enthält. Kurz gesagt, hier war die Funktion, die ich in streaming.py ersetzt habe, um diese Frage zu lösen.

def _read_loop(self, resp): 

    while self.running and not resp.isclosed(): 

     # Note: keep-alive newlines might be inserted before each length value. 
     # read until we get a digit... 
     c = '\n' 
     while c == '\n' and self.running and not resp.isclosed(): 
      c = resp.read(1) 
     delimited_string = c 

     # read rest of delimiter length.. 
     d = '' 
     while d != '\n' and self.running and not resp.isclosed(): 
      d = resp.read(1) 
      delimited_string += d 

     try: 
      int_to_read = int(delimited_string) 
      next_status_obj = resp.read(int_to_read) 
      # print 'status_object = %s' % next_status_obj 
      self._data(next_status_obj) 
     except ValueError: 
      pass 

    if resp.isclosed(): 
     self.on_closed(resp) 

Diese Lösung erfordert auch lernen, wie man den Quellcode für das tweepy Paket herunterzuladen, zu modifizieren, und dann die modifizierte Bibliothek in Python installieren. Dies geschieht, indem Sie in Ihr Toplevel-Verzeichnis von tweepy gehen und etwas wie sudo setup.py install eingeben, abhängig von Ihrem System.

Ich habe auch die Programmierer auf GitHub für dieses Paket kommentiert, um sie wissen zu lassen, was geht.

+3

Ich habe ihren Repo gegabelt und diese Lösung installiert, ich warte nur auf eine Pull-Anfrage. Zur Zeit können Sie die feste Version hier ergreifen: https://github.com/robbrit/tweepy – robbrit

+0

@robbrit - Thanks! Ich schätze das wirklich. Ist der Zug schon erledigt? – snakesNbronies

1

Dies ist ein Fall der Ausgabepufferung. Führen Sie python mit -u (ungepuffered) aus, um dies zu verhindern.

Oder Sie können erzwingen, dass der Puffer gelöscht wird, indem Sie nach Ihrer Druckanweisung eine sys.stdout.flush() ausführen.

Weitere Ideen finden Sie unter this answer.

+0

Danke! Ich wusste, dass es etwas Minderwertiges war. – snakesNbronies