天天看點

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/requests/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/requests/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/requests/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/requests/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 次呢。