Django开发中整合新浪微博API

文章来源:http://qinxuye.me/article/sina-weibo-api-in-developing-diango/

Update:如果想了解更多第三方帐号登录,请看这篇文章

随着新浪微博用户日益增加,我们有时候会考虑在自己的网站中整合新浪微博。比如说我现在的独立博客。

在我的博客中做到整合主要就这几方面:我写一篇文章,就会同步发送至微博。同时呢,用户可以用微博帐号登录,并且可以选择把对文章的评论,同步评论到文章的微博。另外,用户可以选择是否把博客留言同步至新浪微博。

新浪微博开放平台地址在这里。文档地址在这里

首先要涉及的问题,就是用户用新浪微博帐号登录的问题,即授权机制。基本方法有两种:

  1. OAuth
  2. Basic auth(需要强调的是,微博开放平台将于6月1日正式停止Basic Auth的支持。因此,此种方法不作讨论了,其实需要用户名和密码的方式本身就不安全。)

OAuth新浪官方的文档在这里。想要了解OAuth技术说明的可以访问官方网站

其实,OAuth的流程还是很简单的。大致如下:

  1. 向API调用获得request token。
  2. 将用户重定向到授权页(auth url)。
  3. 用户输入用户名和密码完成授权。重定向到Callback_url。
  4. 用request token向新浪微博换取access token。
  5. 完成。

大致了解了OAuth的原理以后,由于我们是整合至Django,自然需要下载微博SDK的Python版

不过,在全部开始前,你得先向新浪微博申请你的应用。申请地址在这里。这里要强调的是,日后应用需要申请审核,因为只有审核通过后,在来源中才能显示个性的应用名。所以,在申请的时候,注意应用介绍信息的完整,以及应用分类的填写正确。(在本例中,我们的分类是合作网站。)

申请完成以后将会得到你的应用的App KeyApp Secret

回到授权用户登录的话题。允许新浪微博帐号接入,首先我们需要在urlpatterns中添加几个URL。如下:

?
1
2
3
4
5
urlpatterns = patterns( 'projectname.appname.views' ,
     url(r '^log/$' , 'login' , name = 'log' ),
     url(r '^logincheck/$' , 'login_check' , name = 'logcheck' ),
     url(r '^logout/$' , 'logout' , name = 'logout' ),
)

接着,我们开始views文件。代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
基于django的新浪微博oauth views
需要django的session支持
"""
 
from django.http import HttpResponseRedirect
 
from weibopy.auth import OAuthHandler, WeibopError
from weibopy import oauth
 
consumer_key = '' # 设置你申请的appkey
consumer_secret = '' # 设置你申请的appkey对于的secret
 
class WebOAuthHandler(OAuthHandler):
 
     def get_authorization_url_with_callback( self , callback, signin_with_twitter = False ):
         """Get the authorization URL to redirect the user"""
         try :
             # get the request token
             self .request_token = self ._get_request_token()
 
             # build auth request and return as url
             if signin_with_twitter:
                 url = self ._get_oauth_url( 'authenticate' )
             else :
                 url = self ._get_oauth_url( 'authorize' )
             request = oauth.OAuthRequest.from_token_and_callback(
                 token = self .request_token, callback = callback, http_url = url
             )
             return request.to_url()
         except Exception, e:
             raise WeibopError(e)
 
 
def _get_referer_url(request):
     referer_url = request.META.get( 'HTTP_REFERER' , '/' )
     host = request.META[ 'HTTP_HOST' ]
     if referer_url.startswith( 'http' ) and host not in referer_url:
         referer_url = '/' # 避免外站直接跳到登录页而发生跳转错误
     return referer_url
 
def _oauth():
     """获取oauth认证类"""
     return WebOAuthHandler(consumer_key, consumer_secret)
 
def login(request):
     # 保存最初的登录url,以便认证成功后跳转回来
     back_to_url = _get_referer_url(request)
     request.session[ 'login_back_to_url' ] = back_to_url
 
     # 获取oauth认证url
     login_backurl = request.build_absolute_uri( '/logincheck' )
     auth_client = _oauth()
     auth_url = auth_client.get_authorization_url_with_callback(login_backurl)
     # 保存request_token,用户登录后需要使用它来获取access_token
     request.session[ 'oauth_request_token' ] = auth_client.request_token
     # 跳转到登录页面
     return HttpResponseRedirect(auth_url)
 
def login_check(request):
     """用户成功登录授权后,会回调此方法,获取access_token,完成授权"""
     verifier = request.GET.get( 'oauth_verifier' , None )
     auth_client = _oauth()
     # 设置之前保存在session的request_token
     request_token = request.session[ 'oauth_request_token' ]
     del request.session[ 'oauth_request_token' ]
 
     auth_client.set_request_token(request_token.key, request_token.secret)
     access_token = auth_client.get_access_token(verifier)
     # 保存access_token,以后访问只需使用access_token即可
     request.session[ 'oauth_access_token' ] = access_token
 
     # 跳转回最初登录前的页面
     back_to_url = request.session.get( 'login_back_to_url' , '/' )
     return HttpResponseRedirect(back_to_url)
 
def logout(request):
     """用户登出,直接删除access_token"""
     del request.session[ 'oauth_access_token' ]
     back_to_url = _get_referer_url(request)
     return HttpResponseRedirect(back_to_url)

在完成了授权的代码之后,接着我们就要知道如何向新浪微博作发送消息等操作了。其实,在下载的SDK下的exanples文件夹(没错,其实是examples,这英文水平,吐槽不能)中的例子基本上拿来改改就可以直接使用了。拿oauthSetTokenUpdate.py来说,我们就可以照着这么写:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# -*- coding: utf-8 -*-
 
from weibopy.auth import OAuthHandler
from weibopy.api import API
 
consumer_key = '应用的key'
consumer_secret = '应用的App Secret'
 
auth = OAuthHandler(consumer_key, consumer_secret)
auth_url = auth.get_authorization_url()
print 'Please authorize: ' + auth_url
verifier = raw_input ( 'PIN: ' ).strip()
auth.get_access_token(verifier)
api = API(auth)
 
status = api.update_status(status = 'hello world' , lat = '12.3' , long = '45.6' ) # 注意status必须是UTF-8编码的字符串,经纬度是可以不写的
print status. id
print status.text

运行这个程序就会提示一个URL链接,在浏览器里打开这个链接,并且给予访问权限,就会拿到一串PIN码。把这个PIN码输上去,就会发送一条推了,并且还会显示用户的Access token key和Access token secret。

不过呢,这么做是不是有点太nerd了。其实我们只要知道Access token key和Access token secret之后,就可以直接用它们来创建API对象了:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -*- coding: utf-8 -*-
 
from weibopy.auth import OAuthHandler
from weibopy.api import API
 
consumer_key = '应用的key'
consumer_secret = '应用的App Secret'
token = '用户的Access token key'
tokenSecret = '用户的Access token secret'
 
auth = OAuthHandler(consumer_key, consumer_secret)
auth.setToken(token, tokenSecret)
api = API(auth)
 
status = api.update_status(status = '搞定收工~' )

这个时候,我们可以重构一下代码,写一个weibo类,来实现以上的功能,并且实现一些api的操作。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class weibo( object ):
     def __init__( self ):
         self .consumer_key = consumer_key
         self .consumer_secret = consumer_secret
     
     def getAtt( self , key):
         try :
             return self .obj.__getattribute__(key)
         except Exception, e:
             print e
             return ''
         
     def getAttValue( self , obj, key):
         try :
             return obj.__getattribute__(key)
         except Exception, e:
             print e
             return ''
         
     def auth( self ):
         self .auth = OAuthHandler( self .consumer_key, self .consumer_secret)
         auth_url = self .auth.get_authorization_url()
         print 'Please authorize: ' + auth_url
         verifier = raw_input ( 'PIN: ' ).strip()
         self .auth.get_access_token(verifier)
         self .api = API( self .auth)
      
     def setToken( self , token, tokenSecret):
         self .auth = OAuthHandler( self .consumer_key, self .consumer_secret)
         self .auth.setToken(token, tokenSecret)
         self .api = API( self .auth)
     
     def update( self , message):
         message = message.encode( "utf-8" )
         status = self .api.update_status(status = message)
         self .obj = status
         id = self .getAtt( "id" )       
         return id
         
     def destroy_status( self , id ):
         status = self .api.destroy_status( id )
         self .obj = status
         id = self .getAtt( "id" )       
         return id
     
     def comment( self , id , message):
         comment = self .api.comment( id = id , comment = message)
         self .obj = comment
         mid = self .getAtt( "id" )
         return mid
     
     def comment_destroy ( self , mid):
         comment = self .api.comment_destroy(mid)
         self .obj = comment
         mid = self .getAtt( "id" )
         text = self .getAtt( "text" )
         return mid
     
     def repost( self , id , message):
         post = self .api.repost( id = id , status = message)
         self .obj = post
         mid = self .getAtt( "id" )
         return mid
     
     def get_username( self ):
         if getattr ( self , '_username' , None ) is None :
             self ._username = self .auth.get_username()
         return self ._username

不知道读者还记得我们上面授权部分的代码。在login_check方法代码里,有这样一句话。

?
1
request.session[ 'oauth_access_token' ] = access_token

授权用户的access_token已经保存在session变量中。因此,在用户授权完成时,我们就可以直接使用保存在session中的access_token,像这样:

?
1
2
3
4
5
access_token = request.session.get( 'oauth_access_token' , None )
if access_token is not None :
     weibo_client = weibo()
     weibo_client.setToken(access_token.key, access_token.secret)
     weibo_client.update( '全部完成~' )

以上的例子中只使用了部分API,完整的API手册参考这里

最后,本文参考两篇文章:《django接入新浪微博OAuth》,以及《新浪微博API开发简介之Python篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值