日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

吐血總結(jié),Python Requests庫(kù)使用指南

 LibraryPKU 2019-04-18

源 / 代碼與藝術(shù)  && 編程禪師

requests 庫(kù)是用來(lái)在Python中發(fā)出標(biāo)準(zhǔn)的HTTP請(qǐng)求。它將請(qǐng)求背后的復(fù)雜性抽象成一個(gè)漂亮,簡(jiǎn)單的API,以便你可以專注于與服務(wù)交互和在應(yīng)用程序中使用數(shù)據(jù)。

在本文中,你將看到 requests 提供的一些有用的功能,以及如何針對(duì)你可能遇到的不同情況來(lái)自定義和優(yōu)化這些功能。你還將學(xué)習(xí)如何有效的使用 requests,以及如何防止對(duì)外部服務(wù)的請(qǐng)求導(dǎo)致減慢應(yīng)用程序的速度。

在本教程中,你將學(xué)習(xí)如何:

  • 使用常見(jiàn)的HTTP方法發(fā)送請(qǐng)求

  • 定制你的請(qǐng)求頭和數(shù)據(jù),使用查詢字符串和消息體

  • 檢查你的請(qǐng)求和響應(yīng)的數(shù)據(jù)

  • 發(fā)送帶身份驗(yàn)證的請(qǐng)求

  • 配置你的請(qǐng)求來(lái)避免阻塞或減慢你的應(yīng)用程序

雖然我試圖包含盡可能多的信息來(lái)理解本文中包含的功能和示例,但閱讀此文需要對(duì)HTTP有基礎(chǔ)的了解。

現(xiàn)在讓我們深入了解如何在你的應(yīng)用程序中使用請(qǐng)求!

開始使用 requests

讓我們首先安裝 requests 庫(kù)。為此,請(qǐng)運(yùn)行以下命令:

  1. pip install requests

如果你喜歡使用 Pipenv 管理Python包,你可以運(yùn)行下面的命令:

  1. pipenv install requests

一旦安裝了 requests ,你就可以在應(yīng)用程序中使用它。像這樣導(dǎo)入 requests :

  1. import requests

現(xiàn)在你已經(jīng)都準(zhǔn)備完成了,那么是時(shí)候開始使用 requests 的旅程了。你的第一個(gè)目標(biāo)是學(xué)習(xí)如何發(fā)出GET請(qǐng)求。


GET 請(qǐng)求

HTTP方法(如GET和POST)決定當(dāng)發(fā)出HTTP請(qǐng)求時(shí)嘗試執(zhí)行的操作。除了GET和POST之外,還有其他一些常用的方法,你將在本教程的后面部分使用到。

最常見(jiàn)的HTTP方法之一是GET。GET方法表示你正在嘗試從指定資源獲取或檢索數(shù)據(jù)。要發(fā)送GET請(qǐng)求,請(qǐng)調(diào)用 requests.get() 。

你可以通過(guò)下面方式來(lái)向GitHub的 Root REST API 發(fā)出GET請(qǐng)求:

  1. >>> requests.get( https://api.github.com )

  2. <Response [200]>

恭喜!你發(fā)出了你的第一個(gè)請(qǐng)求。接下來(lái)讓我們更深入地了解該請(qǐng)求的響應(yīng)。


響應(yīng)

Response 是檢查請(qǐng)求結(jié)果的強(qiáng)有力的對(duì)象。讓我們?cè)俅伟l(fā)出相同的請(qǐng)求,但這次將返回值存儲(chǔ)在一個(gè)變量中,以便你可以仔細(xì)查看其屬性和方法:

  1. >>> response = requests.get( https://api.github.com )

在此示例中,你捕獲了 get() 的返回值,該值是 Response 的實(shí)例,并將其存儲(chǔ)在名為 response 的變量中。你現(xiàn)在可以使用 response 來(lái)查看有關(guān)GET請(qǐng)求結(jié)果的全部信息。

狀態(tài)碼

您可以從 Response 獲取的第一部分信息是狀態(tài)碼。狀態(tài)碼會(huì)展示你請(qǐng)求的狀態(tài)。

例如, 200OK 狀態(tài)表示你的請(qǐng)求成功,而 404NOT FOUND 狀態(tài)表示找不到你要查找的資源。還有許多其它的狀態(tài)碼 ,可以為你提供關(guān)于你的請(qǐng)求所發(fā)生的具體情況。

通過(guò)訪問(wèn) .status_code,你可以看到服務(wù)器返回的狀態(tài)碼:

  1. >>> response.status_code

  2. 200

.status_code 返回 200 意味著你的請(qǐng)求是成功的,并且服務(wù)器返回你要請(qǐng)求的數(shù)據(jù)。

有時(shí),你可能想要在代碼中使用這些信息來(lái)做判斷:

  1. if response.status_code == 200:

  2.    print( Success! )

  3. elif response.status_code == 404:

  4.    print( Not Found. )

按照這個(gè)邏輯,如果服務(wù)器返回 200 狀態(tài)碼,你的程序?qū)⒋蛴?Success! 如果結(jié)果是 404 ,你的程序?qū)⒋蛴?NotFound. 。

requests 更進(jìn)一步為你簡(jiǎn)化了此過(guò)程。如果在條件表達(dá)式中使用 Response 實(shí)例,則在狀態(tài)碼介于 200400 之間時(shí)將被計(jì)算為為 True ,否則為 False 。

因此,你可以通過(guò)重寫 if 語(yǔ)句來(lái)簡(jiǎn)化上一個(gè)示例:

  1. if response:

  2.    print( Success! )

  3. else:

  4.    print( An error has occurred. )

技術(shù)細(xì)節(jié) : 因?yàn)?__bool__()Response 上的重載方法 ,因此真值測(cè)試才成立。

這意味著重新定義了 Response 的默認(rèn)行為,用來(lái)在確定對(duì)象的真值時(shí)考慮狀態(tài)碼。

請(qǐng)記住,此方法 不會(huì)驗(yàn)證 狀態(tài)碼是否等于 200 。原因是 200400 范圍內(nèi)的其他狀態(tài)代碼,例如 204NO CONTENT304NOT MODIFIED ,就意義而言也被認(rèn)為是成功的響應(yīng)。

例如, 204 告訴你響應(yīng)是成功的,但是下消息體中沒(méi)有返回任何內(nèi)容。

因此,通常如果你想知道請(qǐng)求是否成功時(shí),請(qǐng)確保使用這方便的簡(jiǎn)寫,然后在必要時(shí)根據(jù)狀態(tài)碼適當(dāng)?shù)靥幚眄憫?yīng)。

假設(shè)你不想在 if 語(yǔ)句中檢查響應(yīng)的狀態(tài)碼。相反,如果請(qǐng)求不成功,你希望拋出一個(gè)異常。你可以使用 .raise_for_status()執(zhí)行此操作:

  1. import requests

  2. from requests.exceptions import HTTPError

  3. for url in [ https://api.github.com , https://api.github.com/invalid ]:

  4.    try:

  5.        response = requests.get(url)

  6.        # If the response was successful, no Exception will be raised

  7.        response.raise_for_status()

  8.    except HTTPError as http_err:

  9.        print(f HTTP error occurred: {http_err} )  # Python 3.6

  10.    except Exception as err:

  11.        print(f Other error occurred: {err} )  # Python 3.6

  12.    else:

  13.        print( Success! )

如果你調(diào)用 .raise_for_status(),將針對(duì)某些狀態(tài)碼引發(fā) HTTPError 異常。如果狀態(tài)碼指示請(qǐng)求成功,則程序?qū)⒗^續(xù)進(jìn)行而不會(huì)引發(fā)該異常。

進(jìn)一步閱讀:如果你不熟悉Python 3.6的 f-strings,我建議你使用它們,因?yàn)樗鼈兪呛?jiǎn)化格式化字符串的好方法。

現(xiàn)在,你對(duì)于如何處理從服務(wù)器返回的響應(yīng)的狀態(tài)碼了解了許多。但是,當(dāng)你發(fā)出GET請(qǐng)求時(shí),你很少只關(guān)心響應(yīng)的狀態(tài)碼。通常,你希望看到更多。接下來(lái),你將看到如何查看服務(wù)器在響應(yīng)正文中返回的實(shí)際數(shù)據(jù)。

響應(yīng)內(nèi)容

GET 請(qǐng)求的響應(yīng)通常在消息體中具有一些有價(jià)值的信息,稱為有效負(fù)載。使用 Response 的屬性和方法,你可以以各種不同的格式查看有效負(fù)載。

要以 字節(jié) 格式查看響應(yīng)的內(nèi)容,你可以使用 .content

  1. >>> response = requests.get( https://api.github.com )

  2. >>> response.content

  3. b {'current_user_url':'https://api.github.com/user','current_user_authorizations_html_url':'https://github.com/settings/connections/applications{/client_id}','authorizations_url':'https://api.github.com/authorizations','code_search_url':'https://api.github.com/search/code?q={query}{&page,per_page,sort,order}','commit_search_url':'https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}','emails_url':'https://api.github.com/user/emails','emojis_url':'https://api.github.com/emojis','events_url':'https://api.github.com/events','feeds_url':'https://api.github.com/feeds','followers_url':'https://api.github.com/user/followers','following_url':'https://api.github.com/user/following{/target}','gists_url':'https://api.github.com/gists{/gist_id}','hub_url':'https://api.github.com/hub','issue_search_url':'https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}','issues_url':'https://api.github.com/issues','keys_url':'https://api.github.com/user/keys','notifications_url':'https://api.github.com/notifications','organization_repositories_url':'https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}','organization_url':'https://api.github.com/orgs/{org}','public_gists_url':'https://api.github.com/gists/public','rate_limit_url':'https://api.github.com/rate_limit','repository_url':'https://api.github.com/repos/{owner}/{repo}','repository_search_url':'https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}','current_user_repositories_url':'https://api.github.com/user/repos{?type,page,per_page,sort}','starred_url':'https://api.github.com/user/starred{/owner}{/repo}','starred_gists_url':'https://api.github.com/gists/starred','team_url':'https://api.github.com/teams','user_url':'https://api.github.com/users/{user}','user_organizations_url':'https://api.github.com/user/orgs','user_repositories_url':'https://api.github.com/users/{user}/repos{?type,page,per_page,sort}','user_search_url':'https://api.github.com/search/users?q={query}{&page,per_page,sort,order}'}

雖然 .content 允許你訪問(wèn)響應(yīng)有效負(fù)載的原始字節(jié),但你通常希望使用 UTF-8 等字符編碼將它們轉(zhuǎn)換為字符串。當(dāng)你訪問(wèn) .text 時(shí), response 將為你執(zhí)行此操作:

  1. >>> response.text

  2. {'current_user_url':'https://api.github.com/user','current_user_authorizations_html_url':'https://github.com/settings/connections/applications{/client_id}','authorizations_url':'https://api.github.com/authorizations','code_search_url':'https://api.github.com/search/code?q={query}{&page,per_page,sort,order}'...}'}

因?yàn)閷?duì) bytes 解碼到 str 需要一個(gè)編碼格式,所以如果你沒(méi)有指定,請(qǐng)求將嘗試根據(jù)響應(yīng)頭來(lái)猜測(cè)編碼格式。你也可以在訪問(wèn) .text 之前通過(guò) .encoding 來(lái)顯式設(shè)置編碼:

  1. >>> response.encoding = utf-8 # Optional: requests infers this internally

  2. >>> response.text

  3. {'current_user_url':'https://api.github.com/user','current_user_authorizations_html_url':'https://github.com/settings/connections/applications{/client_id}','authorizations_url':'https://api.github.com/authorizations','code_search_url':'https://api.github.com/search/code?q={query}{&page,per_page,sort,order}'...}'}

如果你看看響應(yīng),你會(huì)發(fā)現(xiàn)它實(shí)際上是序列化的 JSON 內(nèi)容。要獲取字典內(nèi)容,你可以使用 .text 獲取 str 并使用 json.loads() 對(duì)其進(jìn)行反序列化。但是,完成此任務(wù)的更簡(jiǎn)單方法是使用 .json()

  1. >>> response.json()

  2. { current_user_url : https://api.github.com/user , current_user_authorizations_html_url : https://github.com/settings/connections/applications{/client_id} ...} }

.json() 返回值的類型是字典類型,因此你可以使用鍵值對(duì)的方式訪問(wèn)對(duì)象中的值。

你可以使用狀態(tài)碼和消息體做許多事情。但是,如果你需要更多信息,例如有關(guān) response 本身的元數(shù)據(jù),則需要查看響應(yīng)頭部。

響應(yīng)頭部

響應(yīng)頭部可以為你提供有用的信息,例如響應(yīng)有效負(fù)載的內(nèi)容類型以及緩存響應(yīng)的時(shí)間限制。要查看這些頭部,請(qǐng)?jiān)L問(wèn) .headers

  1. >>> response.headers

  2. { Server : GitHub.com , Date : Mon, 10 Dec 2018 17:49:54 GMT , Content-Type : application/json; charset=utf-8 ,...}

.headers 返回類似字典的對(duì)象,允許你使用鍵來(lái)獲取頭部中的值。例如,要查看響應(yīng)有效負(fù)載的內(nèi)容類型,你可以訪問(wèn) Content-Type

  1. >>> response.headers[ Content-Type ]

  2. application/json; charset=utf-8

但是,這個(gè)類似于字典的頭部對(duì)象有一些特別之處。HTTP規(guī)范定義頭部不區(qū)分大小寫,這意味著我們可以訪問(wèn)這些頭信息而不必?fù)?dān)心它們的大小寫:

  1. >>> response.headers[ content-type ]

  2. application/json; charset=utf-8

無(wú)論您使用 content-type 還是 Content-Type ,你都將獲得相同的值。

現(xiàn)在,你已經(jīng)學(xué)習(xí)了有關(guān) Response 的基礎(chǔ)知識(shí)。你已經(jīng)看到了它最有用的屬性和方法。讓我們退后一步,看看自定義 GET 請(qǐng)求時(shí)你的響應(yīng)如何變化。


查詢字符串參數(shù)

自定義 GET 請(qǐng)求的一種常用方法是通過(guò)URL中的 查詢字符串 參數(shù)傳遞值。要使用 get() 執(zhí)行此操作,請(qǐng)將數(shù)據(jù)傳遞給 params 。例如,你可以使用GitHub的Search API來(lái)查找 requests庫(kù):

  1. import requests

  2. # Search GitHub s repositories for requests

  3. response = requests.get(

  4.     https://api.github.com/search/repositories ,

  5.    params={ q : requests+language:python },

  6. )

  7. # Inspect some attributes of the `requests` repository

  8. json_response = response.json()

  9. repository = json_response[ items ][0]

  10. print(f Repository name: {repository['name']} )  # Python 3.6+

  11. print(f Repository description: {repository['description']} )  # Python 3.6+

通過(guò)將字典 { q :requests + language:python } 傳遞給 .get()params 參數(shù),你可以修改從Search API返回的結(jié)果。

你可以像你剛才那樣以字典的形式或以元組列表形式將 params 傳遞給 get():

  1. >>> requests.get(

  2. ...     https://api.github.com/search/repositories ,

  3. ...     params=[( q , requests+language:python )],

  4. ... )

  5. <Response [200]>

你甚至可以傳 bytes 作為值:

  1. >>> requests.get(

  2. ...     https://api.github.com/search/repositories ,

  3. ...     params=b q=requests+language:python ,

  4. ... )

  5. <Response [200]>

查詢字符串對(duì)于參數(shù)化GET請(qǐng)求很有用。你還可以通過(guò)添加或修改發(fā)送的請(qǐng)求的頭部來(lái)自定義你的請(qǐng)求。


請(qǐng)求頭

要自定義請(qǐng)求頭,你可以使用 headers 參數(shù)將HTTP頭部組成的字典傳遞給 get()。例如,你可以通過(guò) Accept 中指定文本匹配媒體類型來(lái)更改以前的搜索請(qǐng)求,以在結(jié)果中突出顯示匹配的搜索字詞:

  1. import requests

  2. response = requests.get(

  3.     https://api.github.com/search/repositories ,

  4.    params={ q : requests+language:python },

  5.    headers={ Accept : application/vnd.github.v3.text-match+json },

  6. )

  7. # View the new `text-matches` array which provides information

  8. # about your search term within the results

  9. json_response = response.json()

  10. repository = json_response[ items ][0]

  11. print(f Text matches: {repository['text_matches']} )

Accept 告訴服務(wù)器你的應(yīng)用程序可以處理哪些內(nèi)容類型。由于你希望突出顯示匹配的搜索詞,所以使用的是 application/vnd.github.v3.text-match+json,這是一個(gè)專有的GitHub的 Accept 標(biāo)頭,其內(nèi)容為特殊的JSON格式。

在你了解更多自定義請(qǐng)求的方法之前,讓我們通過(guò)探索其他HTTP方法來(lái)拓寬視野。


其他HTTP方法

除了 GET 之外,其他流行的HTTP方法包括 POST`PUT , DELETEHEAD, PATCHOPTIONS。requests 為每個(gè)HTTP方法提供了一個(gè)方法,與 get() `具有類似的結(jié)構(gòu):

  1. >>> requests.post( https:///post , data={ key : value })

  2. >>> requests.put( https:///put , data={ key : value })

  3. >>> requests.delete( https:///delete )

  4. >>> requests.head( https:///get )

  5. >>> requests.patch( https:///patch , data={ key : value })

  6. >>> requests.options( https:///get )

調(diào)用每個(gè)函數(shù)使用相應(yīng)的HTTP方法向httpbin服務(wù)發(fā)出請(qǐng)求。對(duì)于每種方法,你可以像以前一樣查看其響應(yīng):

  1. >>> response = requests.head( https:///get )

  2. >>> response.headers[ Content-Type ]

  3. application/json

  4. >>> response = requests.delete( https:///delete )

  5. >>> json_response = response.json()

  6. >>> json_response[ args ]

  7. {}

每種方法的響應(yīng)中都會(huì)返回頭部,響應(yīng)正文,狀態(tài)碼等。接下來(lái),你將進(jìn)一步了解 POST`PUTPATCH 方法,并了解它們與其他請(qǐng)求類型的區(qū)別。


消息體

根據(jù)HTTP規(guī)范, POST`PUT和不太常見(jiàn)的 PATCH請(qǐng)求通過(guò)消息體而不是通過(guò)查詢字符串參數(shù)傳遞它們的數(shù)據(jù)。使用 requests,你將有效負(fù)載傳遞給相應(yīng)函數(shù)的 data 參數(shù)。

data 接收字典,元組列表,字節(jié)或類文件對(duì)象。你需要將在請(qǐng)求正文中發(fā)送的數(shù)據(jù)調(diào)整為與你交互的服務(wù)的特定格式。

例如,如果你的請(qǐng)求的內(nèi)容類型是 application/x-www-form-urlencoded ,則可以將表單數(shù)據(jù)作為字典發(fā)送:

  1. >>> requests.post( https:///post , data={ key : value })

  2. <Response [200]>

你還可以將相同的數(shù)據(jù)作為元組列表發(fā)送:

  1. >>> requests.post( https:///post , data=[( key , value )])

  2. <Response [200]>

但是,如果需要發(fā)送JSON數(shù)據(jù),則可以使用 json 參數(shù)。當(dāng)你通過(guò) json 傳遞JSON數(shù)據(jù)時(shí), requests 將序列化你的數(shù)據(jù)并為你添加正確的 Content-Type 標(biāo)頭。

requests 作者 Kenneth Reitz 創(chuàng)建的一個(gè)很好的資源。它是一種接收測(cè)試請(qǐng)求并響應(yīng)有關(guān)請(qǐng)求數(shù)據(jù)的服務(wù)。例如,你可以使用它來(lái)檢查基本的POST請(qǐng)求:

  1. >>> response = requests.post( https:///post , json={ key : value })

  2. >>> json_response = response.json()

  3. >>> json_response[ data ]

  4. {'key': 'value'}

  5. >>> json_response[ headers ][ Content-Type ]

  6. application/json

你可以從響應(yīng)中看到服務(wù)器在你發(fā)送請(qǐng)求時(shí)收到了請(qǐng)求數(shù)據(jù)和標(biāo)頭。requests 還以 PreparedRequest 的形式向你提供此信息。


檢查你的請(qǐng)求

當(dāng)你發(fā)出請(qǐng)求時(shí), requests 庫(kù)會(huì)在將請(qǐng)求實(shí)際發(fā)送到目標(biāo)服務(wù)器之前準(zhǔn)備該請(qǐng)求。請(qǐng)求準(zhǔn)備包括像驗(yàn)證頭信息和序列化JSON內(nèi)容等。

你可以通過(guò)訪問(wèn) .request 來(lái)查看 PreparedRequest:

  1. >>> response = requests.post( https:///post , json={ key : value })

  2. >>> response.request.headers[ Content-Type ]

  3. application/json

  4. >>> response.request.url

  5. https:///post

  6. >>> response.request.body

  7. b {'key': 'value'}

通過(guò)檢查 PreparedRequest ,你可以訪問(wèn)有關(guān)正在進(jìn)行的請(qǐng)求的各種信息,例如有效負(fù)載,URL,頭信息,身份驗(yàn)證等。

到目前為止,你已經(jīng)發(fā)送了許多不同類型的請(qǐng)求,但它們都有一個(gè)共同點(diǎn):它們是對(duì)公共API的未經(jīng)身份驗(yàn)證的請(qǐng)求。你遇到的許多服務(wù)可能都希望你以某種方式進(jìn)行身份驗(yàn)證。


身份驗(yàn)證

身份驗(yàn)證可幫助服務(wù)了解你的身份。通常,你通過(guò)將數(shù)據(jù)傳遞到 Authorization 頭信息或服務(wù)定義的自定義頭信息來(lái)向服務(wù)器提供憑據(jù)。你在此處看到的所有請(qǐng)求函數(shù)都提供了一個(gè)名為 auth 的參數(shù),允許你傳遞憑據(jù)。

需要身份驗(yàn)證的一個(gè)示例API的是GitHub的 Authenticated User API。此端點(diǎn)提供有關(guān)經(jīng)過(guò)身份驗(yàn)證的用戶配置文件的信息。要向 AuthenticatedUserAPI 發(fā)出請(qǐng)求,你可以將你的GitHub的用戶名和密碼以元組傳遞給 get()

  1. >>> from getpass import getpass

  2. >>> requests.get( https://api.github.com/user , auth=( username , getpass()))

  3. <Response [200]>

如果你在元組中傳遞給 auth 的憑據(jù)有效,則請(qǐng)求成功。如果你嘗試在沒(méi)有憑據(jù)的情況下發(fā)出此請(qǐng)求,你將看到狀態(tài)代碼為 401Unauthorized :

  1. >>> requests.get( https://api.github.com/user )

  2. <Response [401]>

當(dāng)你以元組形式吧用戶名和密碼傳遞給 auth 參數(shù)時(shí), rqeuests 將使用HTTP的基本訪問(wèn)認(rèn)證方案來(lái)應(yīng)用憑據(jù)。

因此,你可以通過(guò)使用 HTTPBasicAuth 傳遞顯式的基本身份驗(yàn)證憑據(jù)來(lái)發(fā)出相同的請(qǐng)求:

  1. >>> from requests.auth import HTTPBasicAuth

  2. >>> from getpass import getpass

  3. >>> requests.get(

  4. ...     https://api.github.com/user ,

  5. ...     auth=HTTPBasicAuth( username , getpass())

  6. ... )

  7. <Response [200]>

雖然你不需要明確進(jìn)行基本身份驗(yàn)證,但你可能希望使用其他方法進(jìn)行身份驗(yàn)證。requests提供了開箱即用的其他身份驗(yàn)證方法,例如 HTTPDigestAuthHTTPProxyAuth

你甚至可以提供自己的身份驗(yàn)證機(jī)制。為此,你必須首先創(chuàng)建AuthBase的子類。然后,實(shí)現(xiàn) __call __()

  1. import requests

  2. from requests.auth import AuthBase

  3. class TokenAuth(AuthBase):

  4.    '''Implements a custom authentication scheme.'''

  5.    def __init__(self, token):

  6.        self.token = token

  7.    def __call__(self, r):

  8.        '''Attach an API token to a custom auth header.'''

  9.        r.headers[ X-TokenAuth ] = f {self.token}  # Python 3.6+

  10.        return r

  11. requests.get( https:///get , auth=TokenAuth( 12345abcde-token ))

在這里,你自定義的 TokenAuth 接收一個(gè)令牌,然后在你的請(qǐng)求頭中的 X-TokenAuth 頭中包含該令牌。

錯(cuò)誤的身份驗(yàn)證機(jī)制可能會(huì)導(dǎo)致安全漏洞,因此,除非服務(wù)因某種原因需要自定義身份驗(yàn)證機(jī)制,否則你始終希望使用像 BasicOAuth 這樣經(jīng)過(guò)驗(yàn)證的身份驗(yàn)證方案。

在考慮安全性時(shí),讓我們考慮使用 requests 處理SSL證書。


SSL證書驗(yàn)證

每當(dāng)你嘗試發(fā)送或接收的數(shù)據(jù)都很敏感時(shí),安全性就很重要。通過(guò)HTTP與站點(diǎn)安全通信的方式是使用SSL建立加密連接,這意味著驗(yàn)證目標(biāo)服務(wù)器的SSL證書至關(guān)重要。

好消息是 requests 默認(rèn)為你執(zhí)行此操作。但是,在某些情況下,你可能希望更改此行為。

如果要禁用SSL證書驗(yàn)證,請(qǐng)將 False 傳遞給請(qǐng)求函數(shù)的 verify 參數(shù):

  1. >>> requests.get( https://api.github.com , verify=False)

  2. InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

  3.  InsecureRequestWarning)

  4. <Response [200]>

當(dāng)你提出不安全的請(qǐng)求時(shí), requests 甚至?xí)l(fā)出警告來(lái)幫助你保護(hù)數(shù)據(jù)安全。


性能

在使用 requests 時(shí),尤其是在生產(chǎn)應(yīng)用程序環(huán)境中,考慮性能影響非常重要。超時(shí)控制,會(huì)話和重試限制等功能可以幫助你保持應(yīng)用程序平穩(wěn)運(yùn)行。

超時(shí)控制

當(dāng)你向外部服務(wù)發(fā)出請(qǐng)求時(shí),系統(tǒng)將需要等待響應(yīng)才能繼續(xù)。如果你的應(yīng)用程序等待響應(yīng)的時(shí)間太長(zhǎng),則可能會(huì)阻塞對(duì)你的服務(wù)的請(qǐng)求,你的用戶體驗(yàn)可能會(huì)受到影響,或者你的后臺(tái)作業(yè)可能會(huì)掛起。

默認(rèn)情況下, requests 將無(wú)限期地等待響應(yīng),因此你幾乎應(yīng)始終指定超時(shí)時(shí)間以防止這些事情發(fā)生。要設(shè)置請(qǐng)求的超時(shí),請(qǐng)使用 timeout 參數(shù)。timeout 可以是一個(gè)整數(shù)或浮點(diǎn)數(shù),表示在超時(shí)之前等待響應(yīng)的秒數(shù):

  1. >>> requests.get( https://api.github.com , timeout=1)

  2. <Response [200]>

  3. >>> requests.get( https://api.github.com , timeout=3.05)

  4. <Response [200]>

在第一個(gè)請(qǐng)求中,請(qǐng)求將在1秒后超時(shí)。在第二個(gè)請(qǐng)求中,請(qǐng)求將在3.05秒后超時(shí)。

你還可以將元組傳遞給 timeout,第一個(gè)元素是連接超時(shí)(它允許客戶端與服務(wù)器建立連接的時(shí)間),第二個(gè)元素是讀取超時(shí)(一旦你的客戶已建立連接而等待響應(yīng)的時(shí)間):

  1. >>> requests.get( https://api.github.com , timeout=(2, 5))

  2. <Response [200]>

如果請(qǐng)求在2秒內(nèi)建立連接并在建立連接的5秒內(nèi)接收數(shù)據(jù),則響應(yīng)將按原樣返回。如果請(qǐng)求超時(shí),則該函數(shù)將拋出 Timeout 異常:

  1. import requests

  2. from requests.exceptions import Timeout

  3. try:

  4.    response = requests.get( https://api.github.com , timeout=1)

  5. except Timeout:

  6.    print( The request timed out )

  7. else:

  8.    print( The request did not time out )

你的程序可以捕獲 Timeout 異常并做出相應(yīng)的響應(yīng)。

Session對(duì)象

到目前為止,你一直在處理高級(jí)請(qǐng)求API,例如 get()post()。這些函數(shù)是你發(fā)出請(qǐng)求時(shí)所發(fā)生的事情的抽象。為了你不必?fù)?dān)心它們,它們隱藏了實(shí)現(xiàn)細(xì)節(jié),例如如何管理連接。

在這些抽象之下是一個(gè)名為 Session 的類。如果你需要微調(diào)對(duì)請(qǐng)求的控制方式或提高請(qǐng)求的性能,則可能需要直接使用 Session 實(shí)例。

Session 用于跨請(qǐng)求保留參數(shù)。例如,如果要跨多個(gè)請(qǐng)求使用相同的身份驗(yàn)證,則可以使用 session

  1. import requests

  2. from getpass import getpass

  3. # By using a context manager, you can ensure the resources used by

  4. # the session will be released after use

  5. with requests.Session() as session:

  6.    session.auth = ( username , getpass())

  7.    # Instead of requests.get(), you ll use session.get()

  8.    response = session.get( https://api.github.com/user )

  9. # You can inspect the response just like you did before

  10. print(response.headers)

  11. print(response.json())

每次使用 session 發(fā)出請(qǐng)求時(shí),一旦使用身份驗(yàn)證憑據(jù)初始化,憑據(jù)將被保留。

session 的主要性能優(yōu)化以持久連接的形式出現(xiàn)。當(dāng)你的應(yīng)用程序使用 Session 建立與服務(wù)器的連接時(shí),它會(huì)在連接池中保持該連接。當(dāng)你的應(yīng)用程序想要再次連接到同一服務(wù)器時(shí),它將重用池中的連接而不是建立新連接。

最大重試

請(qǐng)求失敗時(shí),你可能希望應(yīng)用程序重試相同的請(qǐng)求。但是,默認(rèn)情況下, requests 不會(huì)為你執(zhí)行此操作。要應(yīng)用此功能,您需要實(shí)現(xiàn)自定義 Transport Adapter。

通過(guò) TransportAdapters,你可以為每個(gè)與之交互的服務(wù)定義一組配置。例如,假設(shè)你希望所有對(duì)于https://api.github.com的請(qǐng)求在最終拋出 ConnectionError 之前重試三次。你將構(gòu)建一個(gè) TransportAdapter,設(shè)置其 max_retries 參數(shù),并將其裝載到現(xiàn)有的 Session

  1. import requests

  2. from requests.adapters import HTTPAdapter

  3. from requests.exceptions import ConnectionError

  4. github_adapter = HTTPAdapter(max_retries=3)

  5. session = requests.Session()

  6. # Use `github_adapter` for all requests to endpoints that start with this URL

  7. session.mount( https://api.github.com , github_adapter)

  8. try:

  9.    session.get( https://api.github.com )

  10. except ConnectionError as ce:

  11.    print(ce)

當(dāng)您將 HTTPAdapter(github_adapter)掛載到 session 時(shí), session將遵循其對(duì)https://api.github.com的每個(gè)請(qǐng)求的配置。

Timeouts, TransportAdaptersSessions 用于保持代碼高效和應(yīng)用程序的魯棒性。


總結(jié)

在學(xué)習(xí)Python中強(qiáng)大的 requests 庫(kù)方面,你已經(jīng)走了很長(zhǎng)的路。

你現(xiàn)在能夠:

  • 使用各種不同的HTTP方法發(fā)出請(qǐng)求,例如GET,POST和PUT

  • 通過(guò)修改請(qǐng)求頭,身份驗(yàn)證,查詢字符串和消息體來(lái)自定義你的請(qǐng)求

  • 檢查發(fā)送到服務(wù)器的數(shù)據(jù)以及服務(wù)器發(fā)回給你的數(shù)據(jù)

  • 使用SSL證書驗(yàn)證

  • 高效的使用 requests 通過(guò)使用 max_retries, timeout, Sessions 和 TransportAdapters

因?yàn)槟鷮W(xué)會(huì)了如何使用 requests,所以你可以使用他們提供的迷人數(shù)據(jù)探索廣泛的Web服務(wù)世界并構(gòu)建出色的應(yīng)用程序了。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多