豆瓣api的使用
04 August 2012
先说下,自己在web开发这里是完全的新手,很多基础的概念也刚刚接触,导致在做oauth认证登陆以及调用api的功能的时候,比较痛苦。但好歹,现在效果上来说,还是实现了。很可能本文写的东西走了弯路,或者在高手眼里根本就是错的,请评论指正,谢谢。
在做四家的oauth的时候,人人,微博,腾讯以及豆瓣的时候,发现其他几家还文档相对清晰,同时由于是实现的oauth2.0,因此实现起来简单;但豆瓣,首先用的是1.0的标准,同时,被人吐槽了超级多的文档,也让我在做的时候非常的不给力。还真是挺奇怪的,为什么豆瓣这样一家这么先锋的互联网企业,在oauth认证的时候还守着1.0标准。不过后期实现下来,发现也不能完全怪豆瓣文档不清晰,他们应该在文档里加一句话,请参考标准oauth1.0协议。
这个link可以验证你计算签名是否计算正确。
下文的代码就以发一条豆瓣说为例子,希望能帮助到大家。完全的oauth认证实现,等项目完成会开源。
import requests
import json
import hashlib
import sys
import urllib
import time
import hmac
import chardet
#douban
def get_signature_base_string(method, url, timestamp, nonce): #计算签名
http_method = method #HTTP方法
base_url = url #API地址
params = [
('oauth_consumer_key', ''), #douban-app-key
('oauth_signature_method', 'HMAC-SHA1'),
('oauth_version','1.0'),
('oauth_token',''), #oauth-token
('oauth_timestamp', timestamp),
('oauth_nonce',nonce),
]
params.sort() #先要排序下
url_params = urllib.quote(urllib.urlencode(params)) #编码
base_string = "%s&%s&%s" % (http_method, urllib.quote(base_url, safe=''),\
url_params)
two = ''#oauth-token-secret
one = ''#douban-app-secret
secret = one + '&' + two #将两个secret联合起来签名
hmac_sha1 = hmac.new(secret, base_string, hashlib.sha1)
hmac_sha1_string = hmac_sha1.digest()
signature = hmac_sha1_string.encode('base64').rstrip()
return signature
url = 'http://api.douban.com/miniblog/saying'
method = 'POST'
timestamp = str(int(time.time()))
nonce = hashlib.md5(str(time.time())).hexdigest()
args = {'oauth_token' : '',#oauth_token
'oauth_consumer_key' : '',\
#douban_app_key
'oauth_signature_method' : 'HMAC-SHA1',
'oauth_signature' : get_signature_base_string(method, url,\
timestamp, nonce),
'oauth_timestamp' : timestamp,
'oauth_version' : '1.0',
'oauth_nonce' : nonce}
#构造的请求参数
ss = ''
for item in args.keys():
ss = ss + (item+'="'+args[item]+'",')
ss = ss + 'OAuth realm=""'
test_entry = """
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns:ns0="http://www.w3.org/2005/Atom" xmlns:db="http://www.douban.com/xmlns/">
<content>发一条豆瓣说,测试,请忽略</content>
</entry>
"""
#所谓的构造一个entry
headers = {'Authorization' : ss,
'Content-type' : 'application/atom+xml'}
#头部必须定义好
my_config = {'verbose': sys.stderr}
r = requests.post(url, data=test_entry, headers=headers, config=my_config)
print r.text
blog comments powered by Disqus