【问题标题】:Tweepy SSLErrorTweepy SSL错误
【发布时间】:2012-08-21 10:33:22
【问题描述】:

我有一个通过 supervisord 启动的 Django 管理命令,它使用 tweepy 来使用 twitter 流 API。

代理运行良好,但我注意到日志中每 10-15 分钟出现一次 SSLError,并且 supervisord 正在重新启动代理。

tweepy 包是最新的,1.11 版。服务器是 ubuntu 12.04 LTS。我已经尝试将 cacert 安装到下面链接中提到的钥匙链中,但没有运气。

Twitter API SSL Root CA Certificate

有什么建议吗?

[2012-08-26 19:28:15,656: ERROR] Error establishing the connection
Traceback (most recent call last):.../.../datasinks.py", line 102, in start
    stream.filter(locations=self.locations)
  File "/site/pythonenv/local/lib/python2.7/site-packages/tweepy/streaming.py", line 228, in filter
    self._start(async)
  File "/site/pythonenv/local/lib/python2.7/site-packages/tweepy/streaming.py", line 172, in _start
    self._run()
  File "/site/pythonenv/local/lib/python2.7/site-packages/tweepy/streaming.py", line 117, in _run
    self._read_loop(resp)
  File "/site/pythonenv/local/lib/python2.7/site-packages/tweepy/streaming.py", line 150, in _read_loop
    c = resp.read(1)
  File "/usr/lib/python2.7/httplib.py", line 541, in read
    return self._read_chunked(amt)
  File "/usr/lib/python2.7/httplib.py", line 574, in _read_chunked
    line = self.fp.readline(_MAXLINE + 1)
  File "/usr/lib/python2.7/socket.py", line 476, in readline
    data = self._sock.recv(self._rbufsize)
  File "/usr/lib/python2.7/ssl.py", line 241, in recv
    return self.read(buflen)
  File "/usr/lib/python2.7/ssl.py", line 160, in read
  return self._sslobj.read(len)
SSLError: The read operation timed out

以下是代码大纲。

from tweepy import API, OAuthHandler
from tweepy.streaming import StreamListener, Stream
# snip other imports

class TwitterSink(StreamListener, TweetSink):

  def __init__(self):
    self.auth = OAuthHandler(settings.TWITTER_OAUTH_CONSUMER_KEY, settings.TWITTER_OAUTH_CONSUMER_SECRET)
    self.auth.set_access_token(settings.TWITTER_OAUTH_ACCESS_TOKEN_KEY, settings.TWITTER_OAUTH_ACCESS_TOKEN_SECRET)
    self.locations = '' # Snip for brevity

  def start(self):
    try:
        stream = Stream(self.auth, self,timeout=60, secure=True)
        stream.filter(locations=self.locations)
    except SSLError as e:
        logger.exception("Error establishing the connection")
    except IncompleteRead as r:
        logger.exception("Error with HTTP connection")

  # snip on_data()
  # snip on_timeout()
  # snip on_error()

【问题讨论】:

  • 如果将timeout 设置为更大的值会怎样?我怀疑你的 Stream 超时了,因为它偶尔会超过 60 秒而没有收到更新。
  • 你应该考虑在GitHub 上打开一个问题,如果你还没有。

标签: python ssl twitter tweepy


【解决方案1】:

证书似乎不是问题。错误只是超时。对我来说,这似乎是 tweepy 的 SSL 处理的问题。 The code 可以处理socket.timeout 并重新打开连接,但不是通过SSLError 到达的超时。

查看ssl 模块code(或docs),但是,我看不出有什么好方法来捕捉它。 SSLError 对象在没有任何参数的情况下被引发,只是一个字符串描述。由于缺乏更好的解决方案,我建议在line 118 of tweepy/streaming.py 之前添加以下内容:

except SSLError, e:
  if 'timeout' not in exception.message.lower(): # support all timeouts
    exception = e
    break
  if self.listener.on_timeout() == False:
    break
  if self.running is False:
    break
  conn.close()
  sleep(self.snooze_time)

为什么它首先会超时是一个很好的问题。我没有什么比重复 Travis Mehlinger 的建议设置更高的timeout 更好的了。

【讨论】:

  • 思维敏捷,浏览代码做得很好。我已经找到了相同的解决方案,并且也会发布我的代码。
【解决方案2】:

这就是我的方法(修改后的解决方案来自这里https://groups.google.com/forum/?fromgroups=#!topic/tweepy/80Ayu1joGJ4):

l = MyListener()
auth = OAuthHandler(settings.CONSUMER_KEY, settings.CONSUMER_SECRET)
auth.set_access_token(settings.ACCESS_TOKEN, settings.ACCESS_TOKEN_SECRET)
# connect to stream
stream = Stream(auth, l, timeout=30.0)
while True:
    # Call tweepy's userstream method with async=False to prevent
    # creation of another thread.
    try:
        stream.filter(follow=reporters, async=False)
         # Normal exit: end the thread
         break
    except Exception, e:
         # Abnormal exit: Reconnect
         logger.error(e)
         nsecs = random.randint(60, 63)
         logger.error('{0}: reconnect in {1} seconds.'.format(
             datetime.datetime.utcnow(), nsecs))
         time.sleep(nsecs)

【讨论】:

  • 为什么是nsecs = random.randint(60, 63)
  • @pomber 不知道,它在原始线程中,我把它留在那里只是因为它没有受伤。虽然问作者可能会有用。
  • 不错的解决方案。但是,捕获Exception 可能会捕获太多。 ImportErrorKeyErrorNameErrorMemoryErrorSyntaxError 和许多其他人也继承自 Exception
  • 谢谢@kichik。好点。我知道,但我在那里感到很懒惰,而且我真的没有其他例外。并且文档建议至少将 Exception 放在那里以避免仅使用 except:.
【解决方案3】:

Github 上提供了另一种替代解决方案:

https://github.com/tweepy/tweepy/pull/132

【讨论】:

    猜你喜欢
    • 2017-06-04
    • 2012-08-26
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多