本文實(shí)例講述了Python requests庫用法。分享給大家供大家參考,具體如下:
requests是Python中一個第三方庫,基于 urllib,采用 Apache2 Licensed 開源協(xié)議的 HTTP 庫。它比 urllib 更加方便,可以節(jié)約我們大量的工作,完全滿足 HTTP 測試需求。接下來將記錄一下requests的使用:
安裝
要使用requests
庫必須先要安裝:
1
|
pip install requests |
創(chuàng)建請求
通過requests
庫發(fā)出一個請求非常簡單,首先我們先導(dǎo)入requests
庫:
1
|
import requests |
現(xiàn)在我們嘗試創(chuàng)建一個請求,用來獲取百度的網(wǎng)頁信息:
1
|
result = requests.get( 'http://www.baidu.com/' ) |
現(xiàn)在我們獲取到了一個Response對象result,我們可以從這個對象中獲得所有我們需要的所有信息。剛剛的栗子是使用的GET請求,接下來將使用requests庫進(jìn)行POST請求:
1
|
result = requests.post( 'http://www.baidu.com/' ,data = {key:value}) |
很簡單對吧?那么其他HTTP請求呢:PUT、DELETE、HEAD和OPTIONS呢?
1
2
3
4
|
result = requests.put( 'http://www.baidu.com/' ,data = {key,value}) result = requests.head( 'http://www.baidu.com/' ) result = requests.delete( 'http://www.baidu.com/' ) result = requests.options( 'http://www.baidu.com/' ) |
在URL中傳遞參數(shù)
你經(jīng)常想要在URL的查詢字符串中發(fā)送某種數(shù)據(jù)。如果你手動構(gòu)建網(wǎng)址,那么這個數(shù)據(jù)會在問號后作為網(wǎng)址中的鍵值對,例如https://www.baidu.com/s?wd=requests。請求允許你使用params關(guān)鍵字參數(shù)將這些參數(shù)作為字符串字典提供。舉個栗子,你想傳遞name=zhangsan并且age=18到https://www.baidu.com/s,你可以這樣寫:
1
2
|
data = { "name" : "zhangsan" , "age" : 18 } result = requests.get( "https://www.baidu.com/s" ,params = data) |
此時我們打印一下URL,發(fā)現(xiàn)該URL已經(jīng)被正確編碼:
1
|
print result.url # https://www.baidu.com/s?name=zhangsan&age=18 |
也可以傳遞一個列表進(jìn)去:
1
2
3
|
data = { "name" : "zhangsan" , "favorite" :[ "football" , "basketball" ]} result = requests.get( "https://www.baidu.com/s" ,params = data) print result.url # https://www.baidu.com/s?name=zhangsan&favorite=football&favorite=basketball |
響應(yīng)內(nèi)容
在上面的例子可以知道,我們每次請求之后都會返回一個對象,我們可以從此對象中獲取響應(yīng)內(nèi)容:
1
2
|
result = requests.get( "https://api.github.com/events" ) print result.text # [{"id":"6924608641","type":"PushEvent",...}] |
二進(jìn)制響應(yīng)內(nèi)容
1
|
print result.content # b'[{"id":"6924656608","type":"CreateEvent",...}]' |
JSON格式的響應(yīng)內(nèi)容,如果解碼失敗,result.json()將會引發(fā)異常
1
|
print result.json() # [{"id":"6924608641","type":"PushEvent",...}] |
請求將自動解碼來自服務(wù)器的內(nèi)容。大多數(shù)unicode字符集都是無縫解碼的。我們也可以根據(jù)如下方法獲取當(dāng)前的編碼:
1
|
print result.encoding |
如果響應(yīng)的內(nèi)容并不是你想要的編碼格式,你可以在調(diào)用result.text
之前,對result.encoding
進(jìn)行賦值,給予新的編碼格式。
要檢查一個請求是否成功,使用result.raise_for_status()
或者result.status_code
來檢查是否你期望的
套接字響應(yīng)
在極少數(shù)情況下,你希望從服務(wù)器中獲得是原始套接字響應(yīng),你可以通過result.raw
來獲取。如果你想這樣做,確保你設(shè)置stream=True
在你的初始請求。一旦你這樣操作了,你可以這樣:
1
2
3
|
result = requests.get( "https://api.github.com/events" ,stream = True ) print result.raw # <urllib3.response.HTTPResponse object at 0x10ce52dd8> print result.raw.read( 10 ) # b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03' |
通常情況下,我們使用如下這種模式來保存正在流式傳輸?shù)膬?nèi)容:
1
2
3
|
with open ( "info.txt" , "wb" ) as f: for item in result.iter_content(chunk_size = 128 ): f.write(item) |
自定義頭部
如果你想將自定義請求頭添加到請求當(dāng)中,只需要傳遞一個字典到headers參數(shù)即可。例如,在請求中指定我們的請求代理:
1
2
|
header = { "user-agent" : 'my_test/0001' } result = requests.get( "https://api.github.com/events" ,headers = header) |
注意,請求頭的值必須是一個字符串,byte類型的字符串或者unicode。雖然允許unicode,但還是避免使用unicode
復(fù)雜的post請求
通常情況下,你想要發(fā)送一些表單編碼數(shù)據(jù),就像HTML表單一樣。要做到這一點(diǎn),你只需要將字典傳遞給data參數(shù)即可:
1
2
|
infoDict = { "name" : "張三" } result = requests.post( 'http://127.0.0.1:5000/test/post' ,data = infoDict) |
你也可以傳遞一個元組數(shù)據(jù):
1
2
|
tupleInfo = ( "name" , "張三" ) result = requests.post( 'http://127.0.0.1:5000/test/post' ,data = tupleInfo) |
有時你需要發(fā)送一些非編碼格式的數(shù)據(jù),即你發(fā)送的是一個string而不是dict,那么數(shù)據(jù)將會直接發(fā)送:
1
2
3
|
import json infoDict = { "name" : "張三" } result = requests.post( 'http://127.0.0.1:5000/test/post' ,data = json.dumps(infoDict)) |
如果你想要發(fā)送一個字典數(shù)據(jù),你可以通過它使用json參數(shù),它會自動編碼:
1
2
|
infoDict = { "name" : "張三" } result = requests.post( 'http://127.0.0.1:5000/test/post' ,json = infoDict) |
注意,如果你傳遞了data參數(shù)或者files,那么json將會被忽略
post上傳文件
requests上傳文件其實(shí)很簡單:
1
2
|
with open ( 'info.txt' , 'rb' ) as f: result = requests.post( 'http://localhost:5000/post' ,files = { "files" :f}) |
響應(yīng)狀態(tài)碼
我們執(zhí)行完一個請求之后,我們可以使用如下方法查看狀態(tài)碼,檢測請求是否成功:
1
2
|
result = requests.get( 'http://localhost:5000/get' ) print result.status_code # 200 |
當(dāng)返回200,表示請求執(zhí)行成功,我們還可以使用如下方法判斷請求是否成功,True為成功,F(xiàn)alse不成功:
1
|
print result.staatus_code = = requests.codes.ok # True |
當(dāng)我們執(zhí)行一個錯誤的請求(4XX客戶端錯誤,5XX服務(wù)器錯誤)時,我們可以以下方法來拋出異常進(jìn)行檢車:
1
2
3
|
result = requests.get( 'http://localhost:5000/get' ) print result.status_code # 404 print result.raise_for_status() # Traceback (most recent call last): ... |
但是如果我們的請求是執(zhí)行成功的,即狀態(tài)碼為200,此時raise_for_status()
的值將會是None
響應(yīng)頭
我們可以使用Python字典來查看服務(wù)器的響應(yīng)頭文件:
1
|
print result.headers # {'Content-Type': 'text/html; charset=utf-8', 'Content-Length': '2', 'Server': 'Werkzeug/0.12.2 Python/2.7.10', 'Date': 'Sun, 03 Dec 2017 14:15:32 GMT'} |
Cookies
如果響應(yīng)包含了Cookie,你可以這樣快速的訪問它:
1
2
|
result = requests.get( 'http://localhost:5000/get' ) print result.cookies[ 'userName' ] |
或者你需要將自己的Cookie發(fā)送給服務(wù)器,你可以使用cookies參數(shù):
1
2
|
cookie = { 'userName' : 'zhangsan' } result = requests.get( 'http://localhost:5000/get' ,cookies = cookie) |
RequestCookieJar提供了一個完整的接口,適合在多個域和路徑中使用,它將返回一個Cookie,所以它也可以被傳入到cookies參數(shù)中
1
2
3
|
c = requests.cookies.RequestsCookieJar() c. set ( 'userName' , 'zhangsan' ,domain = 'http://localhost:5000' ,path = '/get' ) result = requests.get( 'http://localhost:5000/get' ,cookies = c) |
Session對象
Session對象允許你在請求中保存某些參數(shù),它將在所有由會話實(shí)例創(chuàng)建的請求中保存Cookie,并將使用urllib3連接池。如果你想同一主機(jī)發(fā)出多個請求,則會重新使用底層的TCP連接,這將使性能顯著提高。Session具有主API的所有請求方法:
1
2
3
4
5
|
s = requests.Session() s.get( 'http://httpbin.org/cookies/set/sessioncookie/123456789' ) r = s.get( 'http://httpbin.org/cookies' ) print (r.text) # '{"cookies": {"sessioncookie": "123456789"}}' |
但是請注意,方法級參數(shù)不會保存在請求,即使使用一個session。這個栗子只會發(fā)送第一個請求的Cookie,不會發(fā)送第二個:
1
2
3
4
5
6
|
result = s.get( 'http://httpbin.org/cookies' , cookies = { 'from-my' : 'browser' }) print (result.text) # '{"cookies": {"from-my": "browser"}}' result = s.get( 'http://httpbin.org/cookies' ) print (result.text) # '{"cookies": {}}' |
請求和響應(yīng)對象
每當(dāng)你發(fā)起一個GET請求,你都在做兩件事。首先,構(gòu)造一個Request
將被發(fā)送到服務(wù)器的對象來請求或查詢某個資源。其次,Response
一旦從服務(wù)器中獲得響應(yīng),就會生成一個對象。該Response
對象包含服務(wù)器鎖返回的所有信息,并且還包含Request
你最初創(chuàng)建的對象。這是一個簡單的請求,從維基百科的服務(wù)器獲取一些非常重要的信息:
1
|
result = requests.get( 'http://en.wikipedia.org/wiki/Monty_Python' ) |
現(xiàn)在我們需要獲取服務(wù)器發(fā)送給我們的頭文件信息:
1
|
print result.headers |
如果我們需要獲取發(fā)送給服務(wù)器的頭文件信息,我們可以這樣:
1
|
print result.request.headers |
SSL證書驗(yàn)證
請求將驗(yàn)證HTTPS請求的SSL證書,就像Web瀏覽器一樣。默認(rèn)情況下,啟用SSL驗(yàn)證,如果無法驗(yàn)證SSL證書,將會引發(fā)SSLError:
1
2
|
result = reqests.get( 'https://kyfw.12306.cn/otn/login/init' ) # requests.exceptions.SSLError: ("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",) |
為了避免出現(xiàn)這個錯誤,我們可以將CA證書的CA_BUNDLE文件或目錄傳遞給verify參數(shù)里面:
1
|
result = reqests.get( 'https://kyfw.12306.cn/otn/login/init' ,verify = '/path/...' ) |
或者使用Session方式存儲起來:
1
2
3
|
s = Session() s.verify = '/path/...' result = s.get( 'https://kyfw.12306.cn/otn/login/init' ) |
如果將verify參數(shù)設(shè)置為False,請求也可以忽略SSL證書:
1
|
result = requests.get( 'https://kyfw.12306.cn/otn/login/init' ,verify = False ) |
希望本文所述對大家Python程序設(shè)計(jì)有所幫助。
原文鏈接:https://blog.csdn.net/y472360651/article/details/78785770