网站调用新浪微博内容(使用新浪微博API:创建SDK中的Web应用准备)
优采云 发布时间: 2021-10-31 13:04网站调用新浪微博内容(使用新浪微博API:创建SDK中的Web应用准备)
在《使用新浪微博API:创建SDK》一文中,我们准备了用于编写Web应用程序的SDK,可以在命令行上测试成功。现在,我们可以在Web网站中集成和调用新浪微博的API。
微博登录
使用新浪微博API的第一步是允许用户通过微博登录。在您的网站上放置一个“用微博账号登录”链接,指向一个网站的URL,例如/signin。代码显示如下:
/static/i/signin.png
效果如图:
在URL映射处理函数签名中,创建一个APIClient实例,然后调用get_authorize_url()方法获取新浪微博认证的URL,并将用户重定向到该URL。代码显示如下:
def _create_client():
_APP_ID = '12345'
_APP_SECRET = 'abc123xyz'
_REDIRECT_URI = 'http://example.com/callback'
return APIClient(_APP_ID, _APP_SECRET, _REDIRECT_URI)
@get('/signin')
def signin():
client = _create_client()
# 重定向到新浪微博登陆页:
raise seeother(client.get_authorize_url())
用户在新浪微博的认证页面完成登录后,新浪微博会将用户重定向到我们指定的redirect_uri,并附加参数code。处理redirect_uri的函数会提取参数代码,然后获取登录用户的访问令牌。代码显示如下:
@get('/callback')
def callback():
client = _create_client()
r = client.request_access_token(ctx.request['code'])
access_token, expires_in, uid = r.access_token, r.expires_in, r.uid
在获取access token的同时,新浪微博也会返回access token的过期时间和用户ID。SDK 将过期时间转换为 UNIX 时间戳并返回。
获取到的访问令牌,然后可以使用登录用户的身份调用 API 以进一步获取用户详细信息。代码显示如下:
@get('/callback')
def callback():
...
client.set_access_token(access_token, expires_in)
user = client.users.show.get(uid=uid)
logging.info(json.dump(user)) # { "uid": 1234, "screen_name": "Michael", … }
紧接着,网站必须判断该用户是否是第一次访问,如果是,则在数据库中创建一条记录,如果该用户已经存在,则更新该用户的相关信息。由于uid是用户在新浪微博上的唯一ID号,因此可以作为主键来存储用户信息。同时,访问令牌和过期时间一起存储在数据库中。代码显示如下:
@get('/callback')
def callback():
...
if (_is_user_exist(uid)):
_update_user(user, access_token, expires_in)
else:
_create_user(user, access_token, expires_in)
最后一步是在您的 网站 上使用会话或 cookie 来识别用户已登录。然后,该用户可以作为登录名访问您的 网站。
调用接口
获得用户授权后,即可调用API。例如,列出用户关注的微博列表,代码如下:
@get('/list')
def list_weibo():
user = _user_from_session()
client = _create_client()
client.set_access_token(user.auth_token, user.expired_time)
r = client.statuses.home_timeline.get()
return Template('list.html', statuses = r.statuses)
在HTML模板中,可以将JSON格式的状态列表转成HTML,代码如下:
L = []
for st in statuses:
L.append('''
%s
%s
%s
''' % (st.user.profile_image_url, st.user.screen_name, st.text)
print ''.join(L)
CSS处理后的最终HTML效果如下:
不过仔细观察,我们输出的微博和新浪微博官网是不一样的。官网会把@和http和#topic#开头的文字改成超链接。如何处理@某某某、#主题#和链接?下面是一个JavaScript正则匹配方案,代码如下:
var g_all = /(\@[^\s\&\:\)\uff09\uff1a\@]+)|(\#[^\#]+\#)|(http\:\/\/[a-zA-Z0-9\_\/\.\-]+)/g;
var g_at = /^\@[^\s\&\:\)\uff09\uff1a\@]+$/;
var g_topic = /^\#[^\#]+\#$/;
var g_link = /^http\:\/\/[a-zA-Z0-9\_\/\.\-]+$/;
function format_text(t) {
ss = t.replace('').split(g_all);
L = []
$.each(ss, function(index, s) {
if (s===undefined)
return;
if (g_at.test(s)) {
L.push('' + s + '');
}
else if (g_topic.test(s)) {
L.push('' + s + '');
}
else if (g_link.test(s)) {
L.push('' + s + '');
}
else {
L.push(s);
}
});
return L.join('');
}
在微博上发帖
发布微博的API是status/update,需要通过POST调用。发布微博代码如下:
@post('/update')
def statuses_update():
text = ctx.request['text']
user = _user_from_session()
client = _create_client()
client.set_access_token(user.auth_token, user.expired_time)
r = client.statuses.update.post(status=text)
return True
本文演示了网站:
本文源代码可从GitHub下载: