问题得到解决,在邮件结束时看到解决方案
我需要帮助来估算我的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)
答案 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)