1. 程式人生 > >python requests 高階用法

python requests 高階用法

HTTP動詞

Requests 提供了幾乎所有HTTP動詞的功能:GET、OPTIONS、HEAD、POST、PUT、PATCH、DELETE。以下內容為使用 Requests 中的這些動詞以及 Github API 提供了詳細示例。

我將從最常使用的動詞 GET 開始。HTTP GET 是一個冪等方法,從給定的 URL 返回一個資源。因而,當你試圖從一個 web 位置獲取資料之時,你應該使用這個動詞。一個使用示例是嘗試從 Github 上獲取關於一個特定 commit 的資訊。假設我們想獲取Requests的commit a050faf 的資訊。我們可以這樣去做:

>>> 
import requests >>> 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()

>>> print commit_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'[email protected]', 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_code
500

額,這是怎麼回事?毫無幫助嘛!原來 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_code
200

>>> issue = json.loads(r.text)

>>> print(issue[u'title'])
Feature any http verb in docs

>>> print(issue[u'comments'])
3

Cool,有 3 個評論。我們來看一下最後一個評論。

>>> r = requests.get(r.url + u'/comments')
>>> r.status_code
200
>>> comments = r.json()
>>> print comments[0].keys()
[u'body', u'url', u'created_at', u'updated_at', u'user', u'id']
>>> print comments[2][u'body']
Probably in 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_code
404

額,這有點古怪哈。可能我們需要驗證身份。那就有點糾結了,對吧?不對。Requests 簡化了多種身份驗證形式的使用,包括非常常見的 Basic Auth。

>>> from requests.auth import HTTPBasicAuth
>>> auth = HTTPBasicAuth('[email protected]', 'not_a_real_password')

>>> r = requests.post(url=url, data=body, auth=auth)
>>> r.status_code
201

>>> 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_code
200

非常好。現在,我們來折磨一下這個叫 Kenneth 的傢伙,我決定要讓他急得團團轉,也不告訴他是我在搗蛋。這意味著我想刪除這條評論。GitHub 允許我們使用完全名副其實的 DELETE 方法來刪除評論。我們來清除該評論。

>>> r = requests.delete(url=url, auth=auth)
>>> r.status_code
204
>>> r.headers['status']
'204 No Content'

很好。不見了。最後一件我想知道的事情是我已經使用了多少限額(ratelimit)。查檢視,GitHub 在響應頭部發送這個資訊,因此不必下載整個網頁,我將使用一個 HEAD 請求來獲取響應頭。

>>> r = requests.head(url=url, auth=auth)
>>> print r.headers
...
'x-ratelimit-remaining': '4995'
'x-ratelimit-limit': '5000'
...

很好。是時候寫個 Python 程式以各種刺激的方式濫用 GitHub 的 API,還可以使用 4995 次呢。