问题描述
我有相同的代码来处理在两台不同机器上运行的 Twitter 用户流.两台机器都是使用 python 2.6.5 的 Ubuntu Lucid,但在我家的机器上,我收到 HTTP Error 401: Unauthorized
而在大学时它运行良好.在两台机器上,当我使用具有相同参数(即消费者密钥、消费者机密、访问令牌和访问密钥)的 curl 时,它都能完美运行.
I have the same piece of coding to deal with Twitter User Stream running on two different machines. Both machines are Ubuntu Lucid using python 2.6.5, but on the machine in my home I receive HTTP Error 401: Unauthorized
while on the university it works perfectly. On both machines it works perfectly when I use curl with the same parameters, i.e., consumer key, consumer secret, acces token, and access key.
请看下面的代码,它是由 Josh 创建的锋利
See the code bellow, it was created by Josh Sharp
from oauth.oauth import OAuthRequest, OAuthSignatureMethod_HMAC_SHA1
from hashlib import md5
import json, time
import random, math, re, urllib, urllib2
STREAM_URL = "https://userstream.twitter.com/2/user.json"
class Token(object):
def __init__(self,key,secret):
self.key = key
self.secret = secret
def _generate_nonce(self):
random_number = ''.join(str(random.randint(0, 9)) for i in range(40))
m = md5(str(time.time()) + str(random_number))
return m.hexdigest()
CONSUMER_KEY = 'consumer_key'
CONSUMER_SECRET = 'consumer_secret'
ACCESS_TOKEN = 'token'
ACCESS_TOKEN_SECRET = 'token_secret'
access_token = Token(ACCESS_TOKEN,ACCESS_TOKEN_SECRET)
consumer = Token(CONSUMER_KEY,CONSUMER_SECRET)
parameters = {
'oauth_consumer_key': CONSUMER_KEY,
'oauth_token': access_token.key,
'oauth_signature_method': 'HMAC-SHA1',
'oauth_timestamp': str(int(time.time())),
'oauth_nonce': access_token._generate_nonce(),
'oauth_version': '1.0',
}
oauth_request = OAuthRequest.from_token_and_callback(access_token,
http_url=STREAM_URL,
parameters=parameters)
signature_method = OAuthSignatureMethod_HMAC_SHA1()
signature = signature_method.build_signature(oauth_request, consumer, access_token)
parameters['oauth_signature'] = signature
data = urllib.urlencode(parameters)
req = urllib2.urlopen("%s?%s" % (STREAM_URL,data))
buffer = ''
# We're using urllib2 to avoid external dependencies
# even though pyCurl actually handles the callbacks
# much more gracefully than this clumsy method.
# We read a byte at a time until we find a newline
# which indicates the end of a chunk.
while True:
chunk = req.read(1)
if not chunk:
print buffer
break
chunk = unicode(chunk)
buffer += chunk
tweets = buffer.split("\n",1)
if len(tweets) > 1:
print tweets[0]
buffer = tweets[1]
我尝试在家中执行时的错误是:
The error when I try to execute in home is:
File "py_stream.py", line 48, in <module>
req = urllib2.urlopen("%s?%s" % (STREAM_URL,data))
File "/usr/lib/python2.6/urllib2.py", line 126, in urlopen
return _opener.open(url, data, timeout)
File "/usr/lib/python2.6/urllib2.py", line 397, in open
response = meth(req, response)
File "/usr/lib/python2.6/urllib2.py", line 510, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python2.6/urllib2.py", line 435, in error
return self._call_chain(*args)
File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain
result = func(*args)
File "/usr/lib/python2.6/urllib2.py", line 518, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 401: Unauthorized
因为它在两台机器上都使用 curl 工作,所以我认为 SSL 认证没有问题.但同时它让我想知道当我在家中使用它时会出现什么问题.
Since it works using curl on both machines, I suppose nothing is wrong related with the SSL certification. But at the same time it makes me wonder what fails when I use it in home.
推荐答案
经过数周试图找出问题所在,我发现时钟与负责 Twitter Stream 的时钟没有很好地同步.因此,Twitter 返回 401:未经授权.
After many weeks trying to find what was the problem, I discovered that the clock was not well synced with the one responsible for the Twitter Stream. And therefore, Twitter returns 401: Unauthorized.
如果你使用的是 Ubuntu,你可以使用 ntpdate 解决这个问题,如下所示:
If you are using Ubuntu, you can solve this problem using ntpdate as following:
sudo ntpdate ntp.ubuntu.com
这篇关于在 Python 中使用 OAuth 的 Twitter 流在两台配置相同的机器上表现不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!