- 引言
- 本书涉及的内容
- 第 1 部分 Python 开发入门
- 第 1 章 Python 入门
- 第 2 章 开发 Web 应用
- 第 3 章 Python 项目的结构与包的创建
- 第 4 章 面向团队开发的工具
- 第 5 章 项目管理与审查
- 第 6 章 用 Mercurial 管理源码
- 第 7 章 完备文档的基础
- 第 8 章 模块分割设计与单元测试
- 第 9 章 Python 封装及其运用
- 第 10 章 用 Jenkins 持续集成
- 第 11 章 环境搭建与部署的自动化
- 第 12 章 应用的性能改善
- 第 13 章 让测试为我们服务
- 第 14 章 轻松使用 Django
- 第 15 章 方便好用的 Python 模块
- 附录 A VirtualBox 的设置
- 附录 B OS(Ubuntu)的设置
15.5 使用 Twitter 的 API
随着 Twitter 在全世界推广,系统与 Twitter 联动的需求越来越常见。现在有不少封装了 Twitter API 的 Python 模块,这里我们以 tweepy 为例学习如何使用 tweepy 模块。tweepy 几乎涵盖了所有 Twitter API,而且能相对灵活地应对 Twitter API 自身的规格变更。下面我们用 Flask 和 tweepy 来简单做一个基于 Web 的时间轴视图。
tweepy
15.5.1 导入 tweepy
如 LIST 15.37 所示,通过 pip 命令安装 tweepy。本书使用了 tweepy 的 3.1.0 版本。
LIST 15.37 用 pip 命令安装 tweepy
$ pip install tweepy
15.5.2 添加应用与获取用户密钥
开发使用 Tiwtter 的 API 的应用时,需要将应用添加到 Twitter Application Management。下面我们来实际操作一下。如图 15.5 所示,Twitter Application Management 可以用 Twitter 账户登录。没有账户时需要新注册一个。登录后会进入 Twitter Apps 页面,该页上显示了所有已添加的应用。
Twitter Application Management
图 15.5 已添加应用的一览页面
添加新应用时,需要点击 Create New App 按钮进入添加页面,然后在该页面输入必填事项,如图 15.6 所示。
图 15.6 用于添加应用的页面
本书所用例子的输入如下。
Name(应用名) | bpbook-example |
Description(应用的说明) | bpbook example |
WebSite(应用的 Web 站点) | http://www.beproud.jp/ |
Callback URL(OAuth 认证后的回调 URL) | http://127.0.0.1:5000/callback |
Yes, I agree(同意使用条款) | 勾选后同意使用条款 |
系统上比较重要的只有 Callback URL 的值。这里指定的是通过 Twitter 站点认证后重定向访问的应用的 URL。我们需要在之后开发的应用中实现这个 URL 的处理。输入所有项目后点击 Create your Twitter application,如果没有问题,系统会提示添加完成,并显示已添加应用的详细信息,如图 15.7 所示。
图 15.7 已添加应用的详细信息(添加完成时)
详细信息页面的 Keys and Access Tokens 标签页的 Application Settings 部分显示了 Consumer Key(用户密钥)和 Consumer Secret(用户机密)字符串。使用 Twitter 的 API 时需要用到这两个字符串以及下面即将学习的访问令牌和访问令牌机密。
Access Level 表示应用可以对用户数据做哪些操作,有 Read-only(只读)、Read and Write(可读写)、Read,Write and Access direct messages(可读写及访问私信)3 种操作可供选择。我们这里开发的时间轴视图只有读取操作,因此用 Read-only 就足够了。
15.5.3 获取访问令牌
OAuth 的访问令牌是为每一个使用应用的用户分别配发的值。可以通过已添加应用的详细信息页面为已添加应用的用户手动配发访问令牌。点击 Keys and Access Tokens 标签页下部的 Create my Access token 即可完成访问令牌的配发。点击 Regenerate My Access Token and Token Secret 可以作废已有令牌并重新配发新的。访问令牌以图 15.8 所示的字符串形式给出。我们将在应用中用到 Access Token(访问令牌)和 Access Token Secret(访问令牌机密)。
图 15.8 获取自己的访问令牌
如果应用只使用自己的 Twitter 账户,那么我们开发应用时只考虑上面获取的访问令牌即可。如果应用需要任意多个用户使用不同的 Twitter 账户,则需要使用基于 Web 的 Authorize URL 方式认证,从应用端获取访问令牌。我们即将开发的时间轴视图属于后者。
15.5.4 调用 Twitter API
用 tweepy 调用 Twitter API 时,需要用到 OAuthHandler 类和 API 类。下面,我们使用前面获取的用户密钥和访问令牌,获取 Twitter 主页上显示的时间轴,代码如 LIST 15.38 所示。
LIST 15.38 tweepy_hello.py
# coding: utf-8 from tweepy import OAuthHandler, API # 用户密钥(本应用的) CONSUMER_KEY = 'Consumer key' CONSUMER_SECRET = 'Consumer secret' # 访问令牌(bpbook 用户的) ACCESS_TOKEN = 'Access token' ACCESS_TOKEN_SECRET = 'Access token secret' def main(): # 生成OAuth 的handler handler = OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET) # 给handler 设置访问令牌 handler.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET) # 生成API 实例 api = API(handler) # 用API 获取时间轴 statuses = api.home_timeline() for status in statuses: # 将获取的状态的前15 个字符输出到页面上 print "%s: %s" % (status.user.screen_name, status.text[:15]) if __name__ == '__main__': main()
请各位自行将上述代码中的 CONSUMER_KEY 、CONSUMER_SECRET 、ACCESS_TOKEN 、ACCESS_TOKEN_SECRET 部分替换为前面获取的值。先在 OAuthHandler 类的构造函数中指定用户密钥和用户机密,然后用 OAuthHandler 的 set_access_token 方法给 handler 设置对应的访问令牌。在 API 类的构造函数中指定 handler 对象,让我们能够使用 API 调用。没有设置访问令牌的 handler 无法使用绝大多数的 API 调用。home_timeline 方法最多可以返回 20 条首页的时间轴信息。
上述代码的执行结果如 LIST 15.39 所示。
LIST 15.39 执行结果
$ python tweepy_hello.py bpbook: 测试 liblar_jp: 【有关添加功能的通知】书籍相关 connpass_jp: 【有关功能修改的通知】多天以来 liblar_jp:【有关维护工作已全面结束的通知】 beproud_jp: BePROUD 公司现在就Web (以下省略)
发生 TweepError: HTTP Error 401: Unauthorized 错误时,需要查看用户密钥和访问令牌是否有误。另外,执行环境的系统时间与实际时间不一致也会导致这个错误。
除 home_timeline 之外,还有许多方法封装了 API。详细内容可以查看 tweepy 文档的 API Reference 来了解。
tweepy API Reference
http://tweepy.readthedocs.org/en/v3.0.0/api.html
在这个例子中,我们是直接在代码中描述访问令牌(ACCESS_TOKEN、ACCESS_TOKEN_SECRET)的。对于只通过单一用户获取时间轴信息或进行发言的应用(比如 TwitterBot 等)而言,由于不需要用于认证的 UI,所以使用这种方法不会有问题。
15.5.5 编写用 Twitter 认证的系统
下面我们编写一个用 Twitter 账户登录(认证)并根据各 Twitter 账户的权限使用 API 的系统。编写这个系统中需要用到 Twitter 的认证页面,还要获取各个账户的访问令牌。从登录的起始处理到使用 API 的处理流程如下所示。
① 用户通过 Web 浏览器访问应用的登录 URL
② 应用从 Twitter 获取请求令牌
③ 应用将获取到的请求令牌保存在会话中
④ 应用向 Twitter 的认证 URL 返回带有令牌属性的重定向响应
⑤ 用户通过 Web 浏览器在 Twitter 的认证页面对应用授权
⑥ 用户根据 Twitter 端的重定向响应,通过 Web 浏览器访问应用的回调 URL(带有令牌属性)
⑦ 应用从会话中还原请求令牌
⑧ 应用从 Twitter 获取用户的访问令牌
⑨ 应用依据访问令牌使用 Twitter 的 API
使用 tweepy 可以轻松完成①的生成带属性的 URL、②的获取令牌、⑨的依据访问令牌使用 Twitter API。下面我们看一下 web 应用,它使用 Flask 和 tweepy 对 Twitter 账户进行认证,然后获取时间轴信息并使之显示在页面上,代码如 LIST 15.40 所示。
LIST 15.40 tweepy_auth.py
# coding: utf-8 from flask import Flask, render_template, session, request, redirect from tweepy import OAuthHandler, API application = Flask(__name__) # 设置用于会话的密钥 application.secret_key = 'my secret key' # 用户密钥 CONSUMER_KEY = 'Consumer key' CONSUMER_SECRET = 'Consumer secret' def get_access_token(): """ 从会话获取访问令牌的函数 """ return session.get('access_token') def set_access_token(access_token): """ 在会话中保存访问令牌的函数 """ session['access_token'] = access_token def get_request_token(key): """ 从会话获取请求令牌的函数 """ return session.get(key) def set_request_token(key, token): """ 在会话中保存请求令牌的函数 """ session[key] = token def get_oauth_handler(): """ 返回Tweepy 的OAuth handler 的函数 """ return OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET) def get_api(access_token): """ 指定访问令牌返回API 实例的函数 """ handler = get_oauth_handler() handler.set_access_token(access_token[0], access_token[1]) api = API(handler) return api def set_user(user): """ 在会话中保存用户信息的函数 """ # 以可JSON 序列化的字典对象格式保存在会话中 session['user'] = {'screen_name': user.screen_name} def get_user(): """ 从会话获取用户信息的函数 """ return session.get('user') def is_login(): """ 返回是否为登录状态 """ return not not get_access_token() def clear_session(): """ 删除会话的值 """ session.clear() @application.route('/') def index(): """ 首页 使用模板显示页面 """ # 根据模板显示页面 return render_template('index.html', is_login=is_login(), user=get_user()) @application.route('/login') def login(): """ 登录URL 开始Twitter 认证 """ handler = get_oauth_handler() # 获取认证URL auth_url = handler.get_authorization_url() # 请求令牌保存在会话中 set_request_token( handler.request_token['oauth_token'], handler.request_token['oauth_token_secret']) # 重定向到认证URL return redirect(auth_url) @application.route('/callback') def callback(): """ 回调URL Twitter 认证后的回调URL """ # 用GET 方法获取OAuth 的回调属性 oauth_token = request.args.get('oauth_token') oauth_verifier = request.args.get('oauth_verifier') # 取消时重定向到首页 if not oauth_token and not oauth_verifier: return redirect('/') # 获取OAuth 的handler handler = get_oauth_handler() # 从会话获取请求令牌并设置给handler request_token = get_request_token(oauth_token) handler.request_token = { 'oauth_token': oauth_token, 'oauth_token_secret': request_token, } # 获取访问令牌 access_token = handler.get_access_token(oauth_verifier) # 将访问令牌保存在会话中 set_access_token(access_token) # 获取API 实例 api = get_api(access_token) # 获取登录用户的信息并保存至会话 set_user(api.me()) # 重定向到首页 return redirect('/') @application.route('/logout') def logout(): """ 登出URL 从会话中删除登录状态的信息 """ # 删除会话中的登录信息 clear_session() # 重定向到首页 return redirect('/') @application.route('/timeline') def timeline(): """ 显示时间轴信息的页面 需要认证 """ # 获取登录状态 if not is_login(): # 没有登录则重定向到首页 return redirect('/') # 从会话获取访问令牌 access_token = get_access_token() if not access_token: # 无法获取访问令牌时 # 清除会话并重新开始 clear_session() return redirect('/') # 获取API 实例 api = get_api(access_token) # 调用Twitter API 获取时间轴信息 statuses = api.home_timeline() # 通过模板显示页面 return render_template('timeline.html', statuses=statuses) if __name__ == '__main__': # 通过IP 地址127.0.0.1 的5000 端口执行应用 application.run('127.0.0.1', 5000, debug=True)
其中,CONSUMER_KEY 、CONSUMER_SECRET 的值需要替换成之前为应用获取的值。在上面的例子中,我们用 Flask 的会话保存了请求令牌。该段代码使用了 index.html 和 timeline.html 两个模板文件,这两个文件保存在 templates 目录下,其内容如 LIST 15.41 所示。
LIST 15.41 templates/index.html
<html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <title>Twitter 认证</title> </head> <body> {% if is_login %} <p> 登录名: {{ user.screen_name }}</p> <ul> <li><a href="/timeline"> 获取时间轴信息</a></li> <li><a href="/logout"> 登出</a></li> </ul> {% else %} <ul> <li><a href="/login"> 登录</a></li> </ul> {% endif %} </body> </html>
index.html 在未认证状态下显示开始认证处理的 URL 链接,在已认证状态下则显示 Twitter 的昵称(登录名)、获取时间轴信息的处理以及登出处理的链接(LIST 15.42)。
LIST 15.42 templates/timeline.html
<html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <title> 时间轴信息的显示</title> </head> <body> <dl> {% for status in statuses %} <dt>{{ status.user.screen_name }}</dt> <dd>{{ status.text }}</dd> {% endfor %} </dl> </body> </html>
timeline.html 用来显示获取到的时间轴信息(状态)。准备好源码及模板后,用 python 命令执行 tweepy_auth.py 启动服务器,代码如 LIST 15.43 所示。
LIST 15.43 用 python 命令执行 tweepy_auth.py
$ python tweepy_auth.py * Running on http://127.0.0.1:5000/ * Restarting with reloader
NOTE
本例是用 5000 端口启动开发服务器的,因此请保证 SSH 隧道的主 OS 与客 OS 的 5000 端口相连接。
启动服务器后,打开 Web 浏览器试着访问 http://127.0.0.1:5000/ 。刚开始时我们处于未登录状态,所以会显示有登录链接的页面。点击登录连接,随后将跳转至 Twitter 的认证页面,我们会看到如图 15.9 所示的应用授权请求信息以及按钮。
图 15.9 Twitter 的应用授权页面
点击页面中的授权按钮之后,页面将重定向到我们添加应用时填写的 Callback URL,处理也将返回到应用端。获取访问令牌和个人信息后,应用显示带有用户名、获取时间轴信息链接以及登出链接的登录状态界面。我们点击获取时间轴信息的链接之后,应用会使用用户的访问令牌获取时间轴信息并显示在页面上。至此,时间轴视图的应用开发完毕。
NOTE
这里介绍的时间轴视图是将访问令牌保存了在会话中,会话一旦过期就需要重新获取令牌。我们可以通过将访问令牌存放在数据库中来避免这一问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论