为什么Requests在尝试访问Twitter的API时会引发此SSLError?

时间:2012-09-09 21:16:17

标签: python twitter openssl python-requests rauth

我试图用rauth用twitter做oauth,但似乎没有出现以下错误:

requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

经过一些测试后,我发现尝试访问api.twitter.com并验证https连接时,请求似乎正在破坏。以下是一个示例,它似乎适用于https://github.com,但https://api.twitter.com失败了:

>>> import requests
>>> requests.get('https://github.com', verify=True)
<Response [200]>
>>> requests.get('https://api.twitter.com/oauth/request_token',verify=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "requests/api.py", line 65, in get
    return request('get', url, **kwargs)
  File "requests/safe_mode.py", line 39, in wrapped
    return function(method, url, **kwargs)
  File "requests/api.py", line 51, in request
    return session.request(method=method, url=url, **kwargs)
  File "requests/sessions.py", line 252, in request
    r.send(prefetch=prefetch)
  File "requests/models.py", line 632, in send
    raise SSLError(e)
requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
>>> requests.get('https://api.twitter.com',verify=True)
[SNIP] Same error as above

这是请求中的错误吗?这应该与rauth正在运行的类似,所以我不确定为什么它不能在我的机器上运行。

来自@ thomas-orozco的一些很好的讨论似乎是一个无法验证G2 VeriSign证书的openssl:http://pastebin.com/ZZj3s5uN

看来我通过使用certool来获得VeriSign CA:

certtool y k=/System/Library/Keychains/SystemCACertificates.keychain | grep -i verisign

chrome / safari正在使用它,而不是命令行上的openssl。我能做些什么来让Requests加载正确的证书吗?

1 个答案:

答案 0 :(得分:0)

我用rauth 0.5.3和请求1.1.0给了这个镜头;作为参考,我正在全新安装OS X 10.8.3。它似乎按预期工作。这是我使用的示例脚本:

from rauth import OAuth1Service

# Get a real consumer key & secret from https://dev.twitter.com/apps/new
twitter = OAuth1Service(
    name='twitter',
    consumer_key='J8MoJG4bQ9gcmGh8H7XhMg',
    consumer_secret='7WAscbSy65GmiVOvMU5EBYn5z80fhQkcFWSLMJJu4',
    request_token_url='https://api.twitter.com/oauth/request_token',
    access_token_url='https://api.twitter.com/oauth/access_token',
    authorize_url='https://api.twitter.com/oauth/authorize',
    base_url='https://api.twitter.com/1/')

request_token, request_token_secret = twitter.get_request_token(verify=True)

authorize_url = twitter.get_authorize_url(request_token)

print 'Visit this URL in your browser: ' + authorize_url
pin = raw_input('Enter PIN from browser: ')

session = twitter.get_auth_session(request_token,
                                   request_token_secret,
                                   method='POST',
                                   data={'oauth_verifier': pin},
                                   verify=True)

params = {'include_rts': 1,  # Include retweets
          'count': 10}       # 10 tweets

r = session.get('statuses/home_timeline.json', params=params, verify=True)

for i, tweet in enumerate(r.json(), 1):
    handle = tweet['user']['screen_name'].encode('utf-8')
    text = tweet['text'].encode('utf-8')
    print '{0}. @{1} - {2}'.format(i, handle, text)

我的建议是尝试更新,如果可以的话,看看产生什么结果。我怀疑urllib3的底层更新有助于解决这种情况。请注意,为了使用&gt;请求1.0.0你必须使用rauth 0.5.x;旧版本与Requests 1.0.0 API更改不兼容。