Requests庫使用

咱們可使用Python內置的urllib包來請求網絡資源。但它用起來比較麻煩,並且缺乏不少實用的高級功能。本文咱們將會介紹一個更加方便的Python第三方庫——Requests的使用。html

安裝Requests

要安裝Requests,只要在終端中運行這個簡單命令便可:python

pip install -i https://pypi.douban.com/simple requests

安裝好Requests後,就能夠開始嘗試使用它啦!nginx

發送請求

使用Requests發送網絡請求很是簡單。導入Requests模塊:git

import requests

而後獲取某個網頁。咱們來獲取Github的公共時間線:github

r = requests.get('https://api.github.com/events')

如今,有了一個名爲rResponse的對象。咱們能夠從這個對象中獲取全部咱們想要的信息。json

傳遞URL參數

咱們可能會想用URL的查詢字符串傳遞某種數據。若是是手動構建URL,那麼數據會以鍵值對的形式置於URL中,跟在一個問號的後面。例如,http://httpbin.org/get?key=valRequests容許咱們使用params關鍵字參數,以一個字符串字典來提供這些參數。舉例來講,若是想傳遞key1=value1key2=value2http://httpbin.org/get,那麼可使用以下代碼:api

import requests

payload = {'name':'viljw', 'cat':'ruby'}
r = requests.get('http://httpbin.org/get', params=payload)

打印輸出該URL,能看到URL已被正確編碼:ruby

print(r.url)

# http://httpbin.org/get?name=viljw&cat=ruby

響應內容

咱們能讀取服務器響應內容。舉個例子:服務器

import requests

r = requests.get("http://httpbin.org/get")
print(r.text)

輸出內容以下:cookie

Requests會自動節碼來自服務器的內容。大多數unicode字符集都能被無縫地解碼。

請求發出後,Requests會基於HTTP頭部對響應的編碼做出有根據的推測。當訪問r.text時,Requests會使用其推測的文本編碼。咱們能夠找出Requests使用了什麼編碼,而且可以使用r.encoding屬性來改變它:

import requests

r = requests.get("http://httpbin.org/get")
print(r.encoding)
r.encoding = 'utf-8'
print(r.encoding)

若是改變了編碼,每當訪問r.textRequests都將會使用r.encoding的新值。

二進制響應內容

對於非文本請求,也能以字節的方式訪問請求響應體。例如,以請求返回的二進制數據建立一張圖片,可使用以下代碼:

import requests
from PIL import Image
from io import BytesIO

r = requests.get("https://github.com/fluidicon.png")
im = Image.open(BytesIO(r.content))
im.show()

JSON響應內容

Requests中有一個內置的JSON解碼器,幫助咱們處理JSON數據:

import requests
from pprint import pprint

payload = {'name':"viljw", 'cat':'ruby'}
r = requests.get("http://httpbin.org/get", params=payload)
pprint(r.json())

定製請求頭

若是想爲請求添加HTTP頭部,只要簡單地傳遞一個dictheaders參數就可。

import requests
from pprint import pprint

headers = {'User-Agent': 'viljw-agent'}
r = requests.get("http://httpbin.org/get", headers=headers)
pprint(r.json())

以下圖所示,User-Agent字段的值已被更改成viljw-agent

POST請求

一般,咱們會想要發送一些編碼爲表單形式的數據——很是像一個HTML表單。要實現這個,只須要簡單地傳遞一個字典給data參數。字典數據在發出請求時會自動編碼爲表單形式:

import requests

payload = {"name":"viljw", "actor":"peter"}
r = requests.post("http://httpbin.org/post", data=payload)
print(r.text)

還能夠給data參數傳入一個元組列表。在表單中多個元素使用同一key的時候,這種方式頗有用:

import requests

payload = [("name","viljw"), ("actor","peter"),("actor",'marry')]
r = requests.post("http://httpbin.org/post", data=payload)
print(r.text)

響應狀態碼

咱們能夠查看響應狀態碼:

import requests

r = requests.get("http://httpbin.org/get")
print(r.status_code)

# 200

爲了方便使用,Requests附帶了也給內置的狀態碼查詢對象:

r.status_code == requests.codes.ok

# True

若是發送了一個錯誤請求(一個4XX客戶端錯誤,或5XX服務器錯誤響應),咱們能夠經過Response.raise_for_status()來拋出異常:

In [1]: import requests

In [2]: bad_r = requests.get('http://httpbin.org/status/404')

In [3]: bad_r.status_code
Out[3]: 404

In [4]: bad_r.raise_for_status()
---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
<ipython-input-4-cdf6910f7d4c> in <module>()
----> 1 bad_r.raise_for_status()

c:\python\lib\site-packages\requests\models.py in raise_for_status(self)
    927
    928         if http_error_msg:
--> 929             raise HTTPError(http_error_msg, response=self)
    930
    931     def close(self):

HTTPError: 404 Client Error: NOT FOUND for url: http://httpbin.org/status/404

但因爲咱們的例子中rstatus_code是200,當咱們調用raise_for_status()時,獲得的是:

In [6]: r.raise_for_status()

# None

響應頭

咱們能夠查看以字典形式的服務器響應頭:

In [7]: r.headers
Out[7]: {'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'gzip', 'Content-Type': 'application/json', 'Date': 'Thu, 03 Oct 2019 07:11:16 GMT', 'Referrer-Policy': 'no-referrer-when-downgrade', 'Server': 'nginx', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'DENY', 'X-XSS-Protection': '1; mode=block', 'Content-Length': '184', 'Connection': 'keep-alive'}

Cookie

若是某個響應中包含一些cookie,能夠快速訪問它們:

In [19]: r = requests.get('https://www.baidu.com')

In [20]: r.cookies
Out[20]: <RequestsCookieJar[Cookie(version=0, name='BDORZ', value='27315', port=None, port_specified=False, domain='.baidu.com', domain_specified=True, domain_initial_dot=True, path='/', path_specified=True, secure=False, expires=1570173564, discard=False, comment=None, comment_url=None, rest={}, rfc2109=False)]>

In [21]: r.cookies['BDORZ']
Out[21]: '27315'

要想發送cookies到服務器,可使用cookies參數:

In [27]: url = 'http://httpbin.org/cookies'

In [28]: cookies = dict(cookies_are="working")

In [29]: r = requests.get(url, cookies=cookies)

In [30]: r.json()
Out[30]: {'cookies': {'cookies_are': 'working'}}

超時

能夠告訴Requests在通過以timeout參數設定的秒數時間以後中止等待響應。

>>> requests.get('http://github.com', timeout=0.001)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)

錯誤與異常

遇到網絡問題(如:DNS查詢失敗、拒絕鏈接等)時,Requests會拋出一個ConnectionError異常。

若是HTTP請求返回了不成功的狀態碼, Response.raise_for_status()會拋出一個HTTPError異常。

若請求超時,則拋出一個Timeout異常。

若請求超過了設定的最大重定向次數,則會拋出一個TooManyRedirects異常。

全部Requests顯式拋出的異常都繼承自 requests.exceptions.RequestException

代理

若是須要使用代理,能夠經過任意請求方法提供proxies參數來配置單個請求:

import requests

proxies = {
    'https': 'https://127.0.0.1:1080'
}

r = requests.get('https://www.google.com', proxies=proxies)
print(r.status_code)

# 200

也能夠經過環境變量HTTP_PROXYHTTPS_PROXY來配置代理。

$ export HTTP_PROXY="http://10.10.1.10:3128"
$ export HTTPS_PROXY="http://10.10.1.10:1080"

$ python
>>> import requests
>>> requests.get("http://example.org")

參考

[1] https://requests-docs-cn.read...

相關文章
相關標籤/搜索