" IncompleteRead"使用Python检索Twitter数据时出错

时间:2014-10-29 18:47:57

标签: python python-2.7 twitter tweepy

运行此程序以使用Python 2.7.8检索Twitter数据时:

#imports
from tweepy import Stream
from tweepy import OAuthHandler
from tweepy.streaming import StreamListener

#setting up the keys
consumer_key = '…………...'
consumer_secret = '………...'
access_token = '…………...'
access_secret = '……………..'

class TweetListener(StreamListener):
# A listener handles tweets are the received from the stream.
#This is a basic listener that just prints received tweets to standard output

def on_data(self, data):
    print (data)
    return True

def on_error(self, status):
    print (status)

#printing all the tweets to the standard output
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)



stream = Stream(auth, TweetListener())

t = u"سوريا"
stream.filter(track=[t])

运行此程序5小时后,我收到此错误消息:

Traceback (most recent call last):
  File "/Users/Mona/Desktop/twitter.py", line 32, in <module>
    stream.filter(track=[t])
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tweepy/streaming.py", line 316, in filter
    self._start(async)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tweepy/streaming.py", line 237, in _start
    self._run()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tweepy/streaming.py", line 173, in _run
    self._read_loop(resp)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tweepy/streaming.py", line 225, in _read_loop
    next_status_obj = resp.read( int(delimited_string) )
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 543, in read
    return self._read_chunked(amt)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 612, in _read_chunked
    value.append(self._safe_read(chunk_left))
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 660, in _safe_read
    raise IncompleteRead(''.join(s), amt)
IncompleteRead: IncompleteRead(0 bytes read, 976 more expected)
>>> 

其实我不知道如何处理这个问题!!!

5 个答案:

答案 0 :(得分:6)

您应该使用stall_warnings参数检查是否未能足够快地处理推文。

stream.filter(track=[t], stall_warnings=True)

这些消息由Tweepy处理(查看实施here),如果您落后,将通知您。落后意味着您无法像Twitter API发送给您那样快速处理推文。来自Twitter文档:

  

如果客户端存在断开连接的危险,则将此参数设置为字符串true将导致定期传递消息。这些消息仅在客户端落后时发送,并且将以大约每5分钟一次的最大速率发送。

理论上,在这种情况下,您应该从API收到disconnect message。但是,情况并非总是如此:

  

流API将尝试传递一条消息,指示流已关闭的原因。请注意,如果断开连接是由于网络问题或客户端读取速度太慢,则可能无法收到此消息。

IncompleteRead也可能是由于临时网络问题造成的,可能永远不会再发生。如果它在大约5个小时后重复发生,落后是一个相当不错的选择。

答案 1 :(得分:2)

我刚遇到这个问题。另一个答案是事实上正确的,因为几乎可以肯定:

  • 您的程序无法跟上流
  • 如果是这样的话,你会得到一个失速警告。

在我的情况下,我正在阅读postgres的推文,以便以后分析,在相当密集的地理区域,以及关键字(伦敦,事实上,约100个关键字)。很有可能,即使您只是打印它,您的本地计算机正在做其他一些事情,并且系统进程优先,因此推文将备份,直到Twitter断开您的身份。 (这通常表现为明显的内存泄漏 - 程序增加,直到它被杀死,或者twitter断开连接 - 以先到者为准。)

这里有意义的是将处理推迟到队列中。所以,我使用了redis和django-rq解决方案 - 在dev上实现了大约3个小时,然后我的生产服务器,包括研究,安装,重新调整现有代码,对我的安装,测试和拼写错误的东西都很愚蠢

现在,在你的django目录(适当的地方 - 直接python应用程序的ymmv)中运行: python manage.py rqworker &

你现在有一个队列!您可以通过更改处理程序来添加作业,如下所示: (在文件顶部)

import django_rq

然后在你的处理程序部分:

def on_data(self, data):
    django_rq.enqueue(print, data)
    return True

顺便说一句 - 如果你对从叙利亚发出的东西感兴趣,而不仅仅是提及叙利亚,那么你可以像这样添加到过滤器:

stream.filter(track=[t], locations=[35.6626, 32.7930, 42.4302, 37.2182]

这是一个以叙利亚为中心的非常粗糙的地理围栏,但它将捡起伊拉克/土耳其的边缘。由于这是一个可选的附加功能,因此值得指出:

  

边界框不作为其他过滤器参数的过滤器。对于   示例track = twitter&amp; locations = -122.75,36.8,-121.75,37.8将匹配   任何包含Twitter(即使是非地理推文)或即将发布的推文   来自旧金山地区。

From this answer,帮助了我,and the twitter docs

编辑:我从你随后的帖子中看到你仍然在使用Twitter API的路上,所以希望你无论如何都要对它进行排序,但希望这对其他人有用! :)

答案 2 :(得分:0)

这对我有用。

l = StdOutListener()
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
stream = Stream(auth, l)
while True:
    try:
        stream.filter(track=['python', 'java'], stall_warnings=True)
    except (ProtocolError, AttributeError):
        continue

答案 3 :(得分:0)

解决方案是在捕获异常后立即重新启动流。

# imports
from tweepy import Stream
from tweepy import OAuthHandler
from tweepy.streaming import StreamListener

# setting up the keys
consumer_key = "XXXXX"
consumer_secret = "XXXXX"
access_token = "XXXXXX"
access_secret = "XXXXX"

# printing all the tweets to the standard output
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)


class TweetListener(StreamListener):
    # A listener handles tweets are the received from the stream.
    # This is a basic listener that just prints received tweets to standard output
    def on_data(self, data):
        print(data)
        return True

    def on_exception(self, exception):
        print('exception', exception)
        start_stream()

    def on_error(self, status):
        print(status)


def start_stream():
    stream = Stream(auth, TweetListener())
    t = u"سوريا"
    stream.filter(track=[t])


start_stream()

答案 4 :(得分:-1)

对我来说,URL指向的后端应用程序直接返回字符串

我将其更改为 返回响应(response = original_message,status = 200,content_type ='application / text')

一开始我只是返回了

之类的文本

返回original_message

我认为此答案仅适用于我的情况