【问题标题】:"IncompleteRead" Error when retrieving Twitter Data using Python使用 Python 检索 Twitter 数据时出现“IncompleteRead”错误
【发布时间】:2014-12-25 15:04:46
【问题描述】:

在运行此程序以使用 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)
>>> 

其实这个问题我也不知道怎么办!!!

【问题讨论】:

  • github.com/tweepy/tweepy/pull/498 这是最近修复的。确保您使用的是最新的 Tweepy
  • 谢谢,我试试,我会更新状态
  • 实际上,当我在 MAC OSX 终端中安装“pip install tweepy”新版本的 tweepy 时,我收到此消息“要求已经满足(使用 --upgrade 升级):tweepy in / Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages 清理...”,请问如何覆盖以前的版本?
  • pip install tweepy --upgrade 。该更新仅在 8 天前推送到 github,因此 pip 可能没有最新版本。您始终可以自己编辑源/检查以确保,我认为更改是〜一行。
  • aha 这与 tweepy2.3 相同,他只是在 tweepy/streaming.py 中添加了“除了(超时,ssl.SSLError,requests.compat.IncompleteRead)作为 exc:”这一行,实际上我已经在 tweepy2.3 有那行 :(

标签: python python-2.7 twitter tweepy


【解决方案1】:

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

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

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

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

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

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

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

【讨论】:

  • 我可能会错过它,但stall_warning 只显示警告以确认错误类型。我相信你没有提供解决方案。我现在有这个问题,并且你可能是对的,所以如果你知道解决方案。如果您与我们分享,我将不胜感激。
【解决方案2】:

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

  • 您的程序跟不上直播
  • 如果出现这种情况,您会收到失速警告。

在我的例子中,我将推文读入 postgres 以供以后分析,跨越相当密集的地理区域,以及关键字(实际上是伦敦,大约 100 个关键字)。很有可能,即使你只是在打印它,你的本地机器正在做很多其他的事情,并且系统进程获得优先权,所以推文会备份,直到 Twitter 断开你的连接。 (这通常表现为明显的内存泄漏 - 程序大小增加直到它被杀死,或者 twitter 断开连接 - 以先到者为准。)

这里有意义的事情是将处理推到队列中。因此,我使用了 redis 和 django-rq 解决方案——在开发服务器和生产服务器上实现了大约 3 个小时,包括研究、安装、重新调整现有代码、安装、测试和拼写错误。 .

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

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

import django_rq

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

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

顺便说一句 - 如果您对来自叙利亚的东西感兴趣,而不仅仅是提及叙利亚,那么您可以像这样添加到过滤器中: p>

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

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

边界框不充当其他过滤器参数的过滤器。为了 例如 track=twitter&locations=-122.75,36.8,-121.75,37.8 将匹配 任何包含 Twitter 一词的推文(甚至是非地理推文)或即将发布 来自旧金山地区。

From this answer,这对我有帮助,and the twitter docs

编辑:我从您后续的帖子中看到,您仍在使用 Twitter API,所以希望您无论如何都能对此进行排序,但希望这对其他人有用! :)

【讨论】:

  • 因为我刚刚对此提出了支持,这让我回来了,如果你能选择其中一个答案,如果他们解决了你的问题@hana,那就太好了 - 无论是我的或路易吉。 :)
【解决方案3】:

这对我有用。

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

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

      我改成

      return Response(response=original_message, status=200, content_type='application/text')
      

      一开始我只是返回了类似的文本

      return original_message
      

      我认为这个答案只适用于我的情况

      【讨论】:

      • 我看不到你的答案和问题之间的联系。
      猜你喜欢
      • 2015-04-09
      • 2019-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      • 2020-05-18
      • 1970-01-01
      相关资源
      最近更新 更多