乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       LibraryPKU 2019-04-18

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

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

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

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

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

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

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

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

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

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

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

      開始使用 requests

      讓我們首先安裝 requests 庫。為此,請(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之外,還有其他一些常用的方法,你將在本教程的后面部分使用到。

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

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

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

      2. <Response [200]>

      恭喜!你發(fā)出了你的第一個(gè)請(qǐng)求。接下來讓我們更深入地了解該請(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 來查看有關(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ā)生的具體情況。

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

      1. >>> response.status_code

      2. 200

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

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

      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)一步為你簡化了此過程。如果在條件表達(dá)式中使用 Response 實(shí)例,則在狀態(tài)碼介于 200400 之間時(shí)將被計(jì)算為為 True ,否則為 False 。

      因此,你可以通過重寫 if 語句來簡化上一個(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)行為,用來在確定對(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)是成功的,但是下消息體中沒有返回任何內(nèi)容。

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

      假設(shè)你不想在 if 語句中檢查響應(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)樗鼈兪呛喕袷交址暮梅椒ā?/span>

      現(xiàn)在,你對(duì)于如何處理從服務(wù)器返回的響應(yīng)的狀態(tài)碼了解了許多。但是,當(dāng)你發(fā)出GET請(qǐng)求時(shí),你很少只關(guān)心響應(yīng)的狀態(tà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 允許你訪問響應(yīng)有效負(fù)載的原始字節(jié),但你通常希望使用 UTF-8 等字符編碼將它們轉(zhuǎn)換為字符串。當(dāng)你訪問 .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è)編碼格式,所以如果你沒有指定,請(qǐng)求將嘗試根據(jù)響應(yīng)頭來猜測(cè)編碼格式。你也可以在訪問 .text 之前通過 .encoding 來顯式設(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ù)的更簡單方法是使用 .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ì)的方式訪問對(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問 .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ì)象,允許你使用鍵來獲取頭部中的值。例如,要查看響應(yīng)有效負(fù)載的內(nèi)容類型,你可以訪問 Content-Type

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

      2. application/json; charset=utf-8

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

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

      2. application/json; charset=utf-8

      無論您使用 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)求的一種常用方法是通過URL中的 查詢字符串 參數(shù)傳遞值。要使用 get() 執(zhí)行此操作,請(qǐng)將數(shù)據(jù)傳遞給 params 。例如,你可以使用GitHub的Search API來查找 requests庫:

      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+

      通過將字典 { 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)求很有用。你還可以通過添加或修改發(fā)送的請(qǐng)求的頭部來自定義你的請(qǐng)求。


      請(qǐng)求頭

      要自定義請(qǐng)求頭,你可以使用 headers 參數(shù)將HTTP頭部組成的字典傳遞給 get()。例如,你可以通過 Accept 中指定文本匹配媒體類型來更改以前的搜索請(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)求的方法之前,讓我們通過探索其他HTTP方法來拓寬視野。


      其他HTTP方法

      除了 GET 之外,其他流行的HTTP方法包括 POST , `PUT , DELETE, HEAD, PATCHOPTIONSrequests 為每個(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)碼等。接下來,你將進(jìn)一步了解 POST`PUTPATCH 方法,并了解它們與其他請(qǐng)求類型的區(qū)別。


      消息體

      根據(jù)HTTP規(guī)范, POST, `PUT和不太常見的 PATCH請(qǐng)求通過消息體而不是通過查詢字符串參數(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)你通過 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ù)。例如,你可以使用它來檢查基本的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 庫會(huì)在將請(qǐng)求實(shí)際發(fā)送到目標(biāo)服務(wù)器之前準(zhǔn)備該請(qǐng)求。請(qǐng)求準(zhǔn)備包括像驗(yàn)證頭信息和序列化JSON內(nèi)容等。

      你可以通過訪問 .request 來查看 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'}

      通過檢查 PreparedRequest ,你可以訪問有關(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ù)了解你的身份。通常,你通過將數(shù)據(jù)傳遞到 Authorization 頭信息或服務(wù)定義的自定義頭信息來向服務(wù)器提供憑據(jù)。你在此處看到的所有請(qǐng)求函數(shù)都提供了一個(gè)名為 auth 的參數(shù),允許你傳遞憑據(jù)。

      需要身份驗(yàn)證的一個(gè)示例API的是GitHub的 Authenticated User API。此端點(diǎn)提供有關(guān)經(jīng)過身份驗(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)求成功。如果你嘗試在沒有憑據(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的基本訪問認(rèn)證方案來應(yīng)用憑據(jù)。

      因此,你可以通過使用 HTTPBasicAuth 傳遞顯式的基本身份驗(yàn)證憑據(jù)來發(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)過驗(yàn)證的身份驗(yàn)證方案。

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


      SSL證書驗(yàn)證

      每當(dāng)你嘗試發(fā)送或接收的數(shù)據(jù)都很敏感時(shí),安全性就很重要。通過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ā)出警告來幫助你保護(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í)間太長,則可能會(huì)阻塞對(duì)你的服務(wù)的請(qǐng)求,你的用戶體驗(yàn)可能會(huì)受到影響,或者你的后臺(tái)作業(yè)可能會(huì)掛起。

      默認(rèn)情況下, requests 將無限期地等待響應(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。

      通過 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 庫方面,你已經(jīng)走了很長的路。

      你現(xiàn)在能夠:

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

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

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

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

      • 高效的使用 requests 通過使用 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)購買等信息,謹(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)論公約