新浪微博 PythonSDK 分析

最初想爬新浪微博,从开发文档中找到了 Python 的 SDK,竟然是廖雪峰写的。链接直接指向它的 Github 仓库,看了看代码不长,于是就认真研读一下,一来学习 Python 的使用,二来也就知道新浪微博 API 的使用方法了。奈何懒癌又犯了,拖了很久没写这篇总结,竟然在某次搜索时发现了作者自己写的创建 SDK 的步骤,加深了自己的理解,就赶紧来开动写总结了。

OAuth2.0认证

新浪微博新版的 API 全部使用OAuth 2.0 进行权限管理。OAtuth2.0第一次听说是查看 Twitter 的开发文档时,当时死活不理解整个调用的过程。ruanyifeng 的这篇博文——理解 OAuth2.0 讲解的还算通俗易懂。

新浪微博的 OAuth2.0的登录验证流程如下:

  1. 用户在您的网站上点击“使用新浪微博登录”,您的网站将用户重定向到新浪微博的OAuth认证页,重定向链接中包含client_id参数作为您的网站ID,redirect_uri参数告诉新浪微博当用户登录成功后,将浏览器重定向到您的网站;
  2. 用户在新浪微博的认证页输入帐号和口令;
  3. 新浪微博认证成功后,将浏览器重定向到您的网站,并附上code参数;
  4. 您的网站通过code参数向新浪微博请求用户的access token;
  5. 您的网站拿到用户的access token后,用户登录完成。

OAuth的access token是提供认证服务的网站(例如新浪微博)生成的令牌,代表一个用户认证信息。在随后的API调用中,传入该access token就代表这个登录用户。

SDK中实现 API 调用的方式

weibo.py 总共有不到330行代码,所以很好奇如何通过330行代码实现了几乎整个微博 API 的调用的。

OAuth 认证过程

使用 API 前,需先设置应用相关的参数,如 APPID、APPSECRET等,然后调用 APIClient。在 APIClient 中,将参数保存:

微博的认证需要打开一个 web 页面,登录微博帐号,然后通过回调 url 将 code 参数传回,实现 OAuth 认证中的1、2、3步骤。于是需要一个获取认证 web 页面的函数

访问返回的页面,登录帐号,页面会重定向到我们设置的 redirect_url 上去,并附带 code 参数。将 code 参数解析出来(当然也可以拷贝出来),再次请求获取 access_token(OAuth 的第四步)

_post发送 post 请求,并返回请求的响应结果(即 JSON 字符串)。通过标准库 json 实现初步解析。在 SDK 中,实现了一个 JsonDict 的类,来实现多种的访问 json 字符串内容的方式(这里用到了 python 类的一些特殊函数):

实现 API 调用

(以下摘自作者原文

考虑到Python是一个动态语言,与传统的静态语言Java、C++等不同,我们可以充分利用动态语言的特性,在不必为每个API都编写函数的情况下,允许客户端按照以下规则调用API。

首先,通过新浪微博文档可以查询到每个API的URL和参数,例如,获取当前登录用户及其所关注用户的最新微博:

其中,access_token对每个API都是必填参数,由APIClient内部处理,然后,将URL的“/”变为“.”,实现链式调用,最后,根据HTTP请求格式调用get()或post(),并传入**kw关键字参数。例如,我们希望能通过如下代码方式调用该API:

这样,用户根据新浪微博的API文档,就可以自己构造出API调用。每个API调用返回值自动转化为JSON对象后返回。

下面,我们来实现该调用。

由于Python的动态特性,调用一个class的方法或字段实际上都是查找相应的属性,当该属性不存在时,Python会调用特殊方法__getattr__()试图获得该属性,因此,我们重写__getattr__()并返回一个_Callable对象即可。代码如下:

_Callable对象也重写了__getattr__()以支持动态调用,并在调用get()或post()方法时返回_Executable对象,代码如下:

_Executable对象虽然是class,但重写了__call__()方法,因此是一个可调用对象,可以直接实现函数调用。代码如下:

这样,用户通过API文档,就可以自行构造出任意API调用的函数链,不但极大地简化了SDK的编写,而且调用接口简单明了。

通过access token发送微博的代码如下:

总结:

其实自己关注的也就是最后一部分,通过统一的方式实现对不同 API 的调用。正如作者所说,Python 是动态语言,通过对 Magic 方法类的动态变化,可以大大提高代码的重用程度。

随着版本的更新,微博也出现了一些新的 API,和上述的调用 URL 不同,因此而不通用。这就需要针对性的实现了,不过只要是 RESTful 的 API 就可以很方便的通过 HTTP 请求实现数据的交互。

发表评论

电子邮件地址不会被公开。 必填项已用*标注