Tweepy SSLError

问题描述:

我有一个Django管理命令,通过supervisord启动,使用tweepy来使用Twitter流媒体API。Tweepy SSLError

该代理工作得很好,但我注意到日志中每隔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() 
+2

如果你设置'timeout'会发生什么到更大的东西?我怀疑你的'Stream'是超时的,因为它偶尔超过60秒没有收到更新。 –

+0

如果你还没有,你应该考虑在[GitHub](https://github.com/tweepy/tweepy)上打开一个问题。 –

证书似乎没有问题。错误只是一个超时。看起来像tweepy的SSL处理问题。 The code配备了处理socket.timeout并重新打开连接,但没有通过SSLError到达超时。但是,我看不到一个很好的方法来捕捉这个问题。 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更好的了。

+0

良好的思维和良好的工作浏览代码。我已经找到了相同的解决方案,并将发布我的代码。 – Dmitry

这是我如何把它(从这里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) 
+0

为什么'nsecs = random.randint(60,63)'? – pomber

+0

@pomber dunno,它在原始线程中,我只是因为没有受到伤害而离开它。尽管问作者可能会有用。 – Dmitry

+0

不错的解决方案。但是,捕捉“例外”可能会抓得太多。 'ImportError','KeyError','NameError','MemoryError','SyntaxError'等等也都是从'Exception'继承的。 – kichik

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

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