HTTP动词
Requests 提供了几乎所有HTTP动词的功能:GET、OPTIONS、HEAD、POST、PUT、PATCH、DELETE。以下内容为使用 Requests 中的这些动词以及 Github API 提供了详细示例。
我将从最常使用的动词 GET 开始。HTTP GET 是一个幂等方法,从给定的 URL 返回一个资源。因而,当你试图从一个 web 位置获取数据之时,你应该使用这个动词。一个使用示例是尝试从 Github 上获取关于一个特定 commit 的信息。假设我们想获取Requests的commit a050faf 的信息。我们可以这样去做:
>>> importrequests>>> r = requests.get('https://api.github.com/repos/kennethreitz/requests/git/commits/a050faf084662f3a352dd1a941f2c7c9f886d4ad')
我们应该确认 GitHub 是否正确响应。如果正确响应,我们想弄清响应内容是什么类型的。像这样去做:
>>> if (r.status_code ==requests.codes.ok):
...print r.headers['content-type']
...
application/json; charset=utf-8
可见,GitHub 返回了 JSON 数据,非常好,这样就可以使用 r.json 方法把这个返回的数据解析成 Python 对象。
>>> commit_data =r.json()>>> printcommit_data.keys()
[u'committer', u'author', u'url', u'tree', u'sha', u'parents', u'message']>>> print commit_data[u'committer']
{u'date': u'2012-05-10T11:10:50-07:00', u'email': u'me@kennethreitz.com', u'name': u'Kenneth Reitz'}>>> print commit_data[u'message']
makin'history
到目前为止,一切都非常简单。嗯,我们来研究一下 GitHub 的 API。我们可以去看看文档,但如果使用 Requests 来研究也许会更有意思一点。我们可以借助 Requests 的 OPTIONS 动词来看看我们刚使用过的 url 支持哪些 HTTP 方法。
>>> verbs =requests.options(r.url)>>>verbs.status_code500
额,这是怎么回事?毫无帮助嘛!原来 GitHub,与许多 API 提供方一样,实际上并未实现 OPTIONS 方法。这是一个恼人的疏忽,但没关系,那我们可以使用枯燥的文档。然而,如果 GitHub 正确实现了 OPTIONS,那么服务器应该在响应头中返回允许用户使用的 HTTP 方法,例如:
>>> verbs = requests.options('http://a-good-website.com/api/cats')>>> print verbs.headers['allow']
GET,HEAD,POST,OPTIONS
转而去查看文档,我们看到对于提交信息,另一个允许的方法是 POST,它会创建一个新的提交。由于我们正在使用 Requests 代码库,我们应尽可能避免对它发送笨拙的 POST。作为替代,我们来玩玩 GitHub 的 Issue 特性。
本篇文档是回应 Issue #482 而添加的。鉴于该问题已经存在,我们就以它为例。先获取它。
>>> r = requests.get('https://api.github.com/repos/kennethreitz/requests/issues/482')>>>r.status_code200
>>> issue =json.loads(r.text)>>> print(issue[u'title'])
Feature any http verbindocs>>> print(issue[u'comments'])3
Cool,有 3 个评论。我们来看一下最后一个评论。
>>> r = requests.get(r.url + u'/comments')>>>r.status_code200
>>> comments =r.json()>>> printcomments[0].keys()
[u'body', u'url', u'created_at', u'updated_at', u'user', u'id']>>> print comments[2][u'body']
Probablyin the "advanced" section
嗯,那看起来似乎是个愚蠢之处。我们发表个评论来告诉这个评论者他自己的愚蠢。那么,这个评论者是谁呢?
>>> print comments[2][u'user'][u'login']
kennethreitz
好,我们来告诉这个叫 Kenneth 的家伙,这个例子应该放在快速上手指南中。根据 GitHub API 文档,其方法是 POST 到该话题。我们来试试看。
>>> body = json.dumps({u"body": u"Sounds great! I'll get right on it!"})>>> url = u"https://api.github.com/repos/kennethreitz/requests/issues/482/comments"
>>> r = requests.post(url=url, data=body)>>>r.status_code404
额,这有点古怪哈。可能我们需要验证身份。那就有点纠结了,对吧?不对。Requests 简化了多种身份验证形式的使用,包括非常常见的 Basic Auth。
>>> from requests.auth importHTTPBasicAuth>>> auth = HTTPBasicAuth('fake@example.com', 'not_a_real_password')>>> r = requests.post(url=url, data=body, auth=auth)>>>r.status_code201
>>> content =r.json()>>> print(content[u'body'])
Sounds great! I'll get right on it.
太棒了!噢,不!我原本是想说等我一会,因为我得去喂我的猫。如果我能够编辑这条评论那就好了!幸运的是,GitHub 允许我们使用另一个 HTTP 动词 PATCH 来编辑评论。我们来试试。
>>> print(content[u"id"])5804413
>>> body = json.dumps({u"body": u"Sounds great! I'll get right on it once I feed my cat."})>>> url = u"https://api.github.com/repos/kennethreitz/requests/issues/comments/5804413"
>>> r = requests.patch(url=url, data=body, auth=auth)>>>r.status_code200
非常好。现在,我们来折磨一下这个叫 Kenneth 的家伙,我决定要让他急得团团转,也不告诉他是我在捣蛋。这意味着我想删除这条评论。GitHub 允许我们使用完全名副其实的 DELETE 方法来删除评论。我们来清除该评论。
>>> r = requests.delete(url=url, auth=auth)>>>r.status_code204
>>> r.headers['status']'204 No Content'
很好。不见了。最后一件我想知道的事情是我已经使用了多少限额(ratelimit)。查查看,GitHub 在响应头部发送这个信息,因此不必下载整个网页,我将使用一个 HEAD 请求来获取响应头。
>>> r = requests.head(url=url, auth=auth)>>> printr.headers
...'x-ratelimit-remaining': '4995'
'x-ratelimit-limit': '5000'...
很好。是时候写个 Python 程序以各种刺激的方式滥用 GitHub 的 API,还可以使用 4995 次呢。