Tweety中位置过滤器的流Twitter运行时间估计

时间:2017-03-10 03:32:54

标签: python twitter geolocation tweepy time-estimation

问题得到解决,在邮件结束时看到解决方案

我需要帮助来估算我的tweepy程序的运行时间,该程序使用位置过滤器调用Twitter Stream API。

在我踢掉之后,它已经运行了超过20分钟,这比我预期的要长。我是Twitter Stream API的新手,并且只使用REST API几天。在我看来,REST API将在几秒钟内给我50条推文,很简单。但是这个Stream请求需要花费更多时间。我的程序没有死在我身上或者没有任何错误。所以我不知道它是否有任何问题。如果是这样,请指出。

总之,如果您认为我的代码是正确的,您能否提供运行时间的估算?如果你认为我的代码错了,你能帮我解决一下吗?

提前谢谢!

以下是代码:

# 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

我尝试了http://docs.tweepy.org/en/v3.4.0/auth_tutorial.html#auth-tutorial的方法显然这对我不起作用......以下是我的代码。你介意给出任何意见吗?如果你有一些工作代码,请告诉我。谢谢!

# 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)

以下是错误消息:

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

问题解决了!请参阅以下解决方案

经过另一轮调试后,这里是一个可能对同一主题感兴趣的人的解决方案:

# 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)

1 个答案:

答案 0 :(得分:2)

核心问题: 我认为你误解了Stream在这里的内容。

Tl;博士:您的代码正在运行,您只是没有对回来的数据做任何事情。

其余的API调用是一次调用信息。您发出请求,Twitter会发回一些信息,这些信息会分配给您的变量。

来自Tweepy的StreamObject(您已经创建为stream)打开了与您的搜索参数的Twitter连接,并且Twitter,以及流,推文到它。永远。

来自Tweepy文档:

  

流式api与REST api完全不同,因为   REST api用于从twitter中提取数据,但是流式api   将消息推送到持久会话。这允许流式api   实时下载比使用REST更多的数据   API。

因此,您需要构建一个处理程序(streamListener,用Tweety的术语),如this one that prints out the tweets.

其他

来自痛苦经历的警告 - 如果您要尝试将推文保存到数据库中:Twitter可以并且将会将对象流式传输给您,速度比将它们保存到数据库要快得多。这将导致您的Stream断开连接,因为Twitter上的推文备份,并且在某个级别的备份(不是实际的短语)上,他们只会断开您的连接。

我通过使用django-rq将保存作业放入一个作业队来处理这个问题 - 这样,我可以每秒处理数百条推文(在峰值时),它会顺利完成。您可以在下面看到我是如何做到的。如果您不使用django作为围绕它的框架,Python-rq也会起作用。 read both方法只是一个从推文中读取并将其保存到postgres数据库的函数。在我的具体情况下,我使用django_rq.enqueue函数通过Django ORM完成了这项工作。

__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)

编辑:您的后续问题是由错误地调用侦听器引起的。

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

你有这个:

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

当您使用()时,您尝试将侦听器作为函数调用。所以它应该是:

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

事实上,可能只是简洁地写成:

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