Twitter stream using OAuth in Python behaving diff

2019-06-28 08:09发布

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.

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

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.

1条回答
疯言疯语
2楼-- · 2019-06-28 09:09

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.

If you are using Ubuntu, you can solve this problem using ntpdate as following:

sudo ntpdate ntp.ubuntu.com
查看更多
登录 后发表回答