博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

web.py连接新浪微博

Posted on 2010-11-09 21:40  三块石头  阅读(7441)  评论(5编辑  收藏  举报

前段时间研究了下新浪微博的API,采用oauth登入(不懂oauth的童鞋请移步http://blog.csdn.net/hereweare2009/archive/2009/03/08/3968582.aspx)。也许是人笨,折腾了良久,算是用web.py成功接入到了新浪。不过在使用过程中,发现新浪微博的python api有点小bug,简单修正了下就OK了。废话不说,上代码:

sina_twitter.py
1 #coding=utf-8
2  import os
3 import sys
4 import key
5 import web
6 from weibopy.auth import OAuthHandler
7 from weibopy.api import API
8 from jinja2 import Environment,FileSystemLoader
9
10 #日志对象
11 def initlog():
12 import logging
13 logger=logging.getLogger("sina_twitter")
14 hd=logging.StreamHandler(sys.stdout)
15 fmt = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
16 hd.setFormatter(fmt)
17 logger.addHandler(hd)
18 logger.setLevel(logging.DEBUG)
19 return logger
20
21 logger=initlog()
22
23 #url映射配置
24 urls = (
25 '/', 'Index',
26 '/callback','CallBack',
27 '/logout','LogOut'
28 )
29
30 app=web.application(urls,globals())
31
32 if web.config.get('_session') is None:
33 #web.py中有三种session机制,本应用采用session保存在本地文件的机制
34 session = web.session.Session(app,web.session.DiskStore("sina_twitter"))
35 web.config._session = session
36 else:
37 session = web.config._session
38
39 #使用jinja2模板渲染文件
40 def render_template(template_name,**context):
41 extensions=context.pop('extensions',[])
42 globals=context.pop("globals",{})
43 jinja_env=Environment(
44 loader=FileSystemLoader(os.path.join(os.path.dirname(__file__),'templates')),
45 extensions=extensions)
46 jinja_env.globals.update(globals)
47 return jinja_env.get_template(template_name).render(context)
48
49 #首页
50 #首先从session中获取access_token,没有就转向新浪微博页面认证
51 #认证成功后将access_token保存在session中
52 class Index:
53 def GET(self):
54 access_token=session.get('access_token',None)
55 if not access_token:
56 auth = OAuthHandler(key.CONSUME_KEY, key.CONSUME_SECRET,web.ctx.get('homedomain')+'/callback')
57 #获得新浪微博的认证url地址
58 auth_url = auth.get_authorization_url()
59 logger.debug("认证地址为:%s"%auth_url)
60 #在session中保存request_token,用于在新浪微博认证通过后换取access_token
61 session.request_token=auth.request_token
62 web.seeother(auth_url)
63 else:
64 auth = OAuthHandler(key.CONSUME_KEY, key.CONSUME_SECRET)
65 auth.access_token=access_token
66 api=API(auth)
67 user=api.verify_credentials()
68 friends=api.friends()
69 return render_template('index.html',friends=friends,user=user)
70
71 #页面回调,新浪微博验证成功后会返回本页面
72 class CallBack:
73 def GET(self):
74 try:
75 ins=web.input()
76 oauth_verifier=ins.get('oauth_verifier',None)
77 request_token=session.get('request_token',None)
78 auth=OAuthHandler(key.CONSUME_KEY, key.CONSUME_SECRET)
79 auth.request_token=request_token
80 #通过oauth_verifier来获取access_token
81 access_token=auth.get_access_token(oauth_verifier)
82 session.access_token=access_token
83 web.seeother("/")
84 except Exception:
85 web.header("Content-Type", "text/html;charset=utf-8")
86 return ':-( 出错了'
87
88 #退出微博,返回到首页
89 class LogOut:
90 def GET(self):
91 del session['access_token']
92 del session['request_token']
93 web.seeother('/')
94
95 if __name__=='__main__':
96 logger.debug("web.py服务开始启动……")
97 app.run()

接下来是新浪的密钥文件,或者说是api key,大家在申请新浪应用时可以得到。比如我的是:

1 CONSUME_KEY= "1610911722"
2 CONSUME_SECRET ="secret key"

由于个人不喜欢web.py模板,所以换成jinja2,感觉后者更直观更好用点:)

index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Hello</title>
</head>
<body>
Hello,
<b>{{user.screen_name}}</b>,您的朋友信息如下: <a href='/logout'>退出</a><p></p>
{% for friend in friends %}
{{friend.screen_name}}-->{{friend.description}}-->{{friend.province}}-->{{friend.city}}
<p></p>
{% endfor %}
</body>
</html>

运行city_twitter.py后,访问http://localhost:8080/,页面就会调转到新浪微博授权页面:

点击"授权"后,页面跳转到首页:

顺便说下新浪微博python api的一个小问题,就是认证成功后页面新浪微博页面不跳转,需要修改下weibopy文件下的auth.py中的第98行,改为:

1 request = oauth.OAuthRequest.from_token_and_callback(
2 token=self.request_token,http_url=url,callback=self.callback
3 )

即传入callback属性。