2017-03-10 3 views
0

Problem solved, VOIR UNE SOLUTION À LA FIN DU POSTEDurée Estimation pour flux Twitter avec filtre Emplacement dans Tweepy

Je besoin d'aide pour estimer le temps en cours d'exécution pour mon programme tweepy appelant Twitter API flux avec filtre emplacement. Après le coup d'envoi, il a fonctionné pendant plus de 20 minutes, ce qui est plus long que ce à quoi je m'attendais. Je suis nouveau sur Twitter Stream API, et j'ai seulement travaillé avec l'API REST pendant quelques jours. Il me semble que l'API REST va me donner 50 tweets en quelques secondes, facile. Mais cette requête Stream prend beaucoup plus de temps. Mon programme n'est pas mort sur moi ou donné aucune erreur. Donc je ne sais pas s'il y a quelque chose qui ne va pas. Si oui, veuillez le signaler. En conclusion, si vous pensez que mon code est correct, pourriez-vous fournir une estimation du temps de fonctionnement? Si vous pensez que mon code est faux, pourriez-vous m'aider à le réparer?

Merci d'avance!

Voici le code:

# Import Tweepy, sys, sleep, credentials.py 
import tweepy, sys 
from time import sleep 
from credentials import * 

# Access and authorize our Twitter credentials from credentials.py 
auth = tweepy.OAuthHandler(consumer_key, consumer_secret) 
auth.set_access_token(access_token, access_token_secret) 
api = tweepy.API(auth) 

box = [-86.33,41.63,-86.20,41.74] 

class CustomStreamListener(tweepy.StreamListener): 
    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 

stream = tweepy.streaming.Stream(auth, CustomStreamListener()).filter(locations=box).items(50) 
stream 

J'ai essayé la méthode de http://docs.tweepy.org/en/v3.4.0/auth_tutorial.html#auth-tutorial Apparemment, il ne fonctionne pas pour moi ... Voici mon code ci-dessous. Pourriez-vous donner votre avis? Faites-moi savoir si vous avez un code de travail. Merci!

# Import Tweepy, sys, sleep, credentials.py 
import tweepy, sys 
from time import sleep 
from credentials import * 

# Access and authorize our Twitter credentials from credentials.py 
auth = tweepy.OAuthHandler(consumer_key, consumer_secret) 
auth.set_access_token(access_token, access_token_secret) 
api = tweepy.API(auth) 

# Assign coordinates to the variable 
box = [-74.0,40.73,-73.0,41.73] 

import tweepy 
#override tweepy.StreamListener to add logic to on_status 
class MyStreamListener(tweepy.StreamListener): 

    def on_status(self, status): 
     print(status.text) 
    def on_error(self, status_code): 
     if status_code == 420: 
      #returning False in on_data disconnects the stream 
      return False 

myStreamListener = MyStreamListener() 
myStream = tweepy.Stream(auth = api.auth, listener=myStreamListener()) 
myStream.filter(track=['python'], locations=(box), async=True) 

Voici le message d'erreur:

Traceback (most recent call last): 
    File "test.py", line 26, in <module> 
    myStream = tweepy.Stream(auth = api.auth, listener=myStreamListener()) 
TypeError: 'MyStreamListener' object is not callable 

Problem solved! VOIR LA SOLUTION CI-DESSOUS

Après une autre série de débogage, voici la solution pour celui qui peut avoir un intérêt dans le même sujet:

# Import Tweepy, sys, sleep, credentials.py 
try: 
    import json 
except ImportError: 
    import simplejson as json 
import tweepy, sys 
from time import sleep 
from credentials import * 

# Access and authorize our Twitter credentials from credentials.py 
auth = tweepy.OAuthHandler(consumer_key, consumer_secret) 
auth.set_access_token(access_token, access_token_secret) 
api = tweepy.API(auth) 

# Assign coordinates to the variable 
box = [-74.0,40.73,-73.0,41.73] 

import tweepy 
#override tweepy.StreamListener to add logic to on_status 
class MyStreamListener(tweepy.StreamListener): 

    def on_status(self, status): 
     print(status.text.encode('utf-8')) 
    def on_error(self, status_code): 
     if status_code == 420: 
      #returning False in on_data disconnects the stream 
      return False 

myStreamListener = MyStreamListener() 
myStream = tweepy.Stream(api.auth, listener=myStreamListener) 
myStream.filter(track=['NYC'], locations=(box), async=True) 

Répondre

2

de base Problème: Je pense que vous êtes mal compris ce que le Stream est ici.

Tl; dr: Votre code fonctionne, vous ne faites rien avec les données qui reviennent.

Le reste de l'appel API est un appel unique pour information. Vous faites une demande, Twitter renvoie des informations qui sont assignées à votre variable. Le StreamObject (que vous avez créé en tant que stream) de Tweepy ouvre une connexion à Twitter avec vos paramètres de recherche, et Twitter, tweete Tweets à celui-ci. Pour toujours.

Des Tweepy docs:

Le api streaming est tout à fait différent du reste api parce que le REST api est utilisé pour extraire des données de Twitter, mais le api streaming pousse des messages à une session persistante. Cela permet à l'API de streaming de télécharger plus de données en temps réel que ce qui aurait pu être fait en utilisant l'API REST .

Donc, vous devez construire un gestionnaire (streamListener, dans la terminologie de tweepy), comme this one that prints out the tweets..

supplémentaires

mot d'avertissement, d'une expérience amère - si vous allez essayer de sauver les tweets à une base de données: Twitter peut, et, des objets de flux pour vous beaucoup plus vite que vous pouvez enregistrer eux à la base de données. Cela entraînera la déconnexion de votre flux, car les tweets sauvegardés sur Twitter, et sur un certain niveau de sauvegarde (pas une phrase réelle), ils vont juste vous déconnecter.

J'ai manipulé ceci en utilisant django-rq pour mettre les travaux de sauvegarde dans une file d'attente de travail - de cette façon, je pourrais manipuler des centaines de tweets par seconde (au pic), et ce serait lisse. Vous pouvez voir comment j'ai fait ça ci-dessous. Python-rq fonctionnerait aussi si vous n'utilisiez pas django comme framework autour de lui. La méthode read both est juste une fonction qui lit à partir du tweet et l'enregistre dans une base de données postgres. Dans mon cas particulier, je l'ai fait via l'ORM de Django, en utilisant la fonction django_rq.enqueue.

__author__ = 'iamwithnail' 

from django.core.management.base import BaseCommand, CommandError 
from django.db.utils import DataError 
from harvester.tools import read_both 
import django_rq 

class Command(BaseCommand): 

    args = '<search_string search_string>' 
    help = "Opens a listener to the Twitter stream, and tracks the given string or list" \ 
      "of strings, saving them down to the DB as they are received." 


    def handle(self, *args, **options): 
     try: 
      import urllib3.contrib.pyopenssl 
      urllib3.contrib.pyopenssl.inject_into_urllib3() 
     except ImportError: 
      pass 

     consumer_key = '***' 
     consumer_secret = '****' 
     access_token='****' 
     access_token_secret_var='****' 
     import tweepy 
     import json 

     # This is the listener, responsible for receiving data 
     class StdOutListener(tweepy.StreamListener): 
      def on_data(self, data): 
       decoded = json.loads(data) 
       try: 
        if decoded['lang'] == 'en': 
         django_rq.enqueue(read_both, decoded) 
        else: 
         pass 
       except KeyError,e: 
        print "Error on Key", e 
       except DataError, e: 
        print "DataError", e 
       return True 


      def on_error(self, status): 
       print status 


     l = StdOutListener() 
     auth = tweepy.OAuthHandler(consumer_key, consumer_secret) 
     auth.set_access_token(access_token, access_token_secret_var) 
     stream = tweepy.Stream(auth, l) 
stream.filter(track=args) 

Éditer: Votre problème suivant est causé par l'appel incorrect de l'écouteur.

myStreamListener = MyStreamListener() #creates an instance of your class 

Où avez-vous ceci:

myStream = tweepy.Stream(auth = api.auth, listener=myStreamListener()) 

Vous essayez d'appeler l'auditeur en fonction lorsque vous utilisez le (). Il doit donc être:

myStream = tweepy.Stream(auth = api.auth, listener=myStreamListener) 

Et en fait, peut sans doute être un peu plus succinctement écrit que:

myStream = tweepy.Stream(api.auth,myStreamListener) 
+0

Nice, @Withnail, je vais jeter un oeil à votre réponse plus tard et regarder dans toutes les bons détails. Merci d'avance pour votre temps et votre attention! J'ai l'intuition que ce sera une bonne conversation et une opportunité d'apprentissage pour moi. Excité. – Counter10000

+0

J'ai essayé la méthode que vous avez mentionnée sur http://docs.tweepy.org/en/v3.4.0/auth_tutorial.html#auth-tutorial Apparemment, ça ne marche pas pour moi ... Mon code de test est ajouté à mon post ci-dessus . Pourriez-vous donner votre avis? Faites-moi savoir si vous avez un code de travail. Merci! – Counter10000

+0

Voir la réponse révisée! – Withnail