使用python requests模塊發(fā)送http請求及接收響應(yīng)的方法
內(nèi)容概要
- 如何構(gòu)建GET 與 POST request 請求消息
- 對 request 的header , query string, message body 定制化
- http header參數(shù) content-type 的設(shè)置
- 分析request, response 消息數(shù)據(jù)
- 通過POST請求向服務(wù)器上傳文件,,以及從服務(wù)器接收文件
- 請求與響應(yīng)使用 json 格式
為什么推薦使用 requests 模塊?
用 python 編寫 http request 消息代碼時,建議用requests庫。因為requests比urllib內(nèi)置庫更為簡捷,requests可以直接構(gòu)造get,post請求并發(fā)送,而urllib.request只能先構(gòu)造get,post請求消息內(nèi)容,然后再發(fā)送。并且requests 模塊提供了更友好的方法與屬性來解析response消息內(nèi)容。
1. 準(zhǔn)備知識
1.1 HTTP request 與 Response 通訊機制
http協(xié)議是基于1種客戶機(client) – 服務(wù)器(server) 的通信模式,它的下層是TCP協(xié)議。
- 所有的請求request 都是由客戶機發(fā)起的
- 服務(wù)器對客戶請求做出響應(yīng)response
- 每個request 都是獨立于其它request消息,服務(wù)器不需要跟蹤request消息的狀態(tài)
1.2 Http Request 請求與響應(yīng)消息
客戶端發(fā)送一個HTTP請求到服務(wù)器的請求消息由四個部分組成
- 請求行(request line)
- 頭部(header)、
- 空行(CLF)
- 報文主體(payload,或body)
下圖給出了請求報文的一般格式。
上圖中,可以看到。Request 請求行第1個字節(jié)為請求方法
, 有時也稱動詞
(verb), 常用的主要有4種方法:GET, POST, PUT, DELETE
。
1.3 Http Response 響應(yīng)消息
服務(wù)器的響應(yīng)消息,也是由4部分組成
狀態(tài)行、頭部、空行和響應(yīng)正文
請求消息與響應(yīng)消息的頭部都是由頭部字段構(gòu)成,它能起到傳遞額外重要信息的作用。 使用首部字段是為了給瀏覽器和服務(wù)器提供報文主體大小、所使用的語言、認(rèn)證信息等內(nèi)容。
頭部字段的格式,如下
字段名: 字段值
如
Content-Type: text/html
就以上述示例來看,首部字段名為 Content-Type,字符串 text/html 是字段值。
另外,字段值對應(yīng)單個 HTTP 首部字段可以有多個值,如下所示。
Keep-Alive: timeout=15, max=100
頭部字段通常也用于攜帶用戶身份信息,如訪問知名站點時,對方通常會在響應(yīng)的頭部添加 set-cookie字段,其中包含用戶id,token等加密后的數(shù)據(jù)。此后的請求的頭部也會添加cookie 字段。
2. 安裝 requests 模塊
安裝requests 模塊非常簡單,
pip install requests
3. 發(fā)送 GET 請求
3.1 request.get() 方法
get()方法用于準(zhǔn)備并發(fā)送 http get 請求至指定url , 并返回response 對象
語法
requests.get(url, params=None, **kwargs)
- url: 擬獲取頁面的url鏈接
- params: url中的額外參數(shù),字典或字節(jié)流格式,可選
**kwargs
: 可選參數(shù).
url 完整格式
最終發(fā)送的完整url, 是將輸入url 與parameters 拼接形成,格式如下:
url格式:http://host_ip:port/path/add?key1=value1&key2=value2
3.2 GET 方法的請求參數(shù) QueryParameters
get方法的請求參數(shù)是通過 params來傳遞的。 其類型為字典,params={ key1: value1, key2: value2 }
response = requests.get( 'https://api.github.com/search/repositories', params={'name': 'Jack','type':'display'}, )
requests 模塊會將url與parameters 拼接成完整的請求消息
ttps://api.github.com/search/repositories?name=Jack&type=display
可能遇到的問題 : 如果GET請求參數(shù)中包含漢字,常會遇到編碼錯誤
主要原因:http協(xié)議對URL參數(shù)的編碼要求是ASCII字符集,而漢字是UTF-8。在發(fā)送時要進行兩次編碼才能將漢字轉(zhuǎn)為ASCII字節(jié)碼:
- 第1次編碼, 用 UTF-8 字符集,每個漢字占3個字節(jié)。
- 第2次編碼,可以用 iso-8859-1,然后再轉(zhuǎn)為ASCII,也可以用其它字符集來轉(zhuǎn)ASCII。
同樣,接收方也要進行兩次解碼,才能正確地還原漢字。
還好,python 內(nèi)置庫urllib 提供了1條命令,1次就可以將漢字轉(zhuǎn)為ASCII編碼。
編碼: urllib.parse.urlencode(dic)
解碼: urllib.parse.unquote(dic or str)
示例代碼
keyword = "天氣預(yù)報" param_list = urllib.parse.urlencode( { 'q' : keyword } ) #包含漢字 header = {'user-Agent':'haha‘} url = 'http://www.baidu.com/s/' response = request.get( url, params=param_list, headers = header )
3.3 get()方法的可選參數(shù)
get()方法的可選參數(shù) **kwargs部分,常見的參數(shù)主要有:
- headers 設(shè)置頭部參數(shù),字典類型
- cookies 設(shè)置cookie,也是字典類型。
- auth, tupe類型,用于基本鑒權(quán)
- proxies 設(shè)置代理服務(wù)器
- stream, 為bool類型,如果請求二進制文件,圖片等應(yīng)設(shè)置為True
- timeout, 超時時間,為秒
headers = { 'user-agent': 'my-app/0.0.1', 'Content-Type': 'text/html; charset=UTF-8' } response = requests.get(url, headers=headers,timeout=10)
3.4 Response 對象常用屬性及方法
查看響應(yīng)消息內(nèi)容 響應(yīng)內(nèi)容的文本格式:response.text
>>> r = requests.get('https://api.github.com/events') >>> r.text '[{"repository":{"open_issues":0,"url":"https://github.com/...
響應(yīng)內(nèi)容的二進制格式: response.content
>>>r.content b'[{"repository":{"open_issues":0,"url":"https://github.com/...
如果響應(yīng)內(nèi) 容是json格式,可以用Response.json()方法轉(zhuǎn)換成 dict類型
>>> r = requests.get('https://api.github.com/events') >>> r.json() [{'repository': {'open_issues': 0, 'url': 'https://github.com/...
分析status_code
收到response后,需要分析響應(yīng)狀態(tài)碼status_code,有必要可以對404, 500等出錯響應(yīng)進行特殊處理。
import requests from requests.exceptions import HTTPError for url in ['https://api.github.com', 'https://api.github.com/invalid']: try: response = requests.get(url) # If the response was successful, no Exception will be raised response.raise_for_status() except HTTPError as http_err: print(f'HTTP error occurred: {http_err}') # Python 3.6 except Exception as err: print(f'Other error occurred: {err}') # Python 3.6 else: print('Success!')
當(dāng)調(diào)用 .raise_for_status()
, 對特定的status_code將產(chǎn)生1個 HTTPError
異常
Status_code
收到響應(yīng)狀態(tài)碼301重定向
如果收到的status_code 為301,可以從response.url中獲取新的url.
response = requests.get("http://192.168.3.100/demo/") new_url = response.url
異常 response 消息
如果發(fā)出request后,收到異常的response, 可以用下面的數(shù)據(jù)檢查 :
>>> response = requests.post('https://httpbin.org/post', json={'key':'value'}) >>> response.request.headers['Content-Type'] 'application/json' >>> response.request.url 'https://httpbin.org/post' >>> response.request.body b'{"key": "value"}'
或?qū)⑺蓄^部字段打印出來:
resp = requests.get(url, headers=header) for head in resp.headers: print(head, ":", resp.headers[head])
output類似于:
Date : Thu, 13 Jul 2023 05:00:49 GMT Server : WSGIServer/0.2 CPython/3.9.4 Content-Type : text/html; charset=utf-8 X-Frame-Options : DENY Content-Length : 3669 X-Content-Type-Options : nosniff Referrer-Policy : same-origin
4. 發(fā)送 POST 請求
4.1 requests.post()方法的使用
與GET請求不同的是, POST 請求參數(shù)是放在 request body 里發(fā)送的,
post() 語法
requests.post(url, data=None, json=None, **kwargs)
POST請求參數(shù)使用data, 或json傳入。data的數(shù)據(jù)類型可以是dict,tuple, list等, json也就是json。
返回類型為 response類型。
# 請求參數(shù)以字典方式坆 post_dict = {'key1': 'value1', 'key2': 'value2'} # 以元組方式傳入 post_tuple = (('key1', 'value1'), ('key1', 'value2')) # 用json格式 post_json = { "some": "data" } headers = { "Content-Type": "application/json" } r1 = requests.post("http://httpbin.org/post", data=post_dict) r2 = requests.post("http://httpbin.org/post", data=post_tuple) r3 = requests.post("http://httpbin.org/post", json=post_json, headers=headers)
收到 Response。 Response對象主要屬性與方法,請參考上一節(jié)內(nèi)容。
HTTP/1.1 200 OK Content-Length: 19 Content-Type: application/json {"success":"true"}
4.2 POST 消息設(shè)置 cookie, header
import requests # 請求數(shù)據(jù) url = 'http://api.shein.com/v2/member/login' cookie = "token=code_space;" header = { "cookie": cookie, "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "keep-alive", "Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" } data = { 'user_id': '123456', 'email': '123456@163.com' } timeout = 0.5 resp = requests.post(url, headers=header, data=data, timeout=timeout) print(resp.text) print(type(resp.json()))
4.3 用 POST請求向服務(wù)器上傳文件
客戶端可通過POST請求,向服務(wù)器上傳文件
#形式1 url = 'http://httpbin.org/post' #定義文件對象 files = {"files":open('test.xls', 'rb')} response = requests.post(url,files = files) print(response.text) #形式2 url ='http://httpbin.org/post' files = {'file': ('t.xls', open('t.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})} r = requests.post(url, files=files) r.text #形式3, 發(fā)送多個文件 url = 'http://httpbin.org/post' files = {'file': ('t.csv', 'bb.csv')} response = requests.post(url, files=files) response.text
4.4 從服務(wù)器接收文件
向服務(wù)器請求1個2進制文件時,stream設(shè)置為True.
r = requests.get('https://api.github.com/events', stream=True) print(r.raw.read(10))
r.raw 是文件原始內(nèi)容,可以用文件的方式讀取,如 r.raw.read(10)。 如果尺寸不大,可直接保存到文件。如果收到的內(nèi)容比較大,用response的 iter_content()方法來分塊保存,以避免內(nèi)存溢出等風(fēng)險
with open(filename, 'wb') as fd: for chunk in r.iter_content(chunk_size=128): fd.write(chunk)
4.5 基本鑒權(quán)
當(dāng)服務(wù)器web應(yīng)用的認(rèn)證采用的是基本鑒權(quán)(Basic authentication) 時,使用auth參數(shù)傳入username與password。 get(), post() 均支持。
from requests.auth import HTTPBasicAuth requests.post(url, auth=HTTPBasicAuth("username", "password"))
5、請求與響應(yīng)頭部的 content-type 參數(shù)說明
上一切,發(fā)送json格式請求參數(shù)時,要設(shè)置頭部參數(shù)"Content-Type": “application/json”,
Content-Type 參數(shù)用于告訴服務(wù)器或瀏覽器,http 消息所包含資源的類型。這個參數(shù)在request 與 response消息中都可能包含,是 response 消息頭部非常關(guān)鍵1個參數(shù),也是開發(fā)者應(yīng)該掌握的1個知識點。其內(nèi)容格式是 IETF’s RFC 6838 標(biāo)準(zhǔn)中的 MIME Type
(Multipurpose Internet Mail Extensions).
先看1個實際消息示例 :
Content-Type: text/html; charset=utf-8 Content-Type: multipart/form-data; boundary=something
content-type 參數(shù)的語法格式:
type/subtype
- type 代表數(shù)據(jù)資源的大類,如 text (文本類型), video(視頻類型)等
- subtype 是資源子類,如,對于 text類,subtype 可能是 plain(純文本),csv 或者html等。
content-type還可以附加參數(shù)
type/subtype;parameter=value
常見情形:當(dāng)type是 text類型,文本內(nèi)容是中文,需添加charset參數(shù),指定編碼類型:Content-Type: text/html;charset=UTF-8
在http協(xié)議以及行業(yè)內(nèi),有很多通用的建議值,最常見的:
application/x-www-form-urlencoded
, 這是提交表單默認(rèn)的content-type設(shè)置, 對應(yīng)form屬性為 enctype=“application/x-www-form-urlencoded”。multipart/form-data
, 用于 form 上傳文件application/json
傳json數(shù)據(jù)text/html
傳網(wǎng)頁text/plain text/xml
傳文本image/jpeg
傳圖片video/mp4
傳MP4視頻
等。
注:
對于"application/x-www-form-urlencoded" 編碼,如果兩端都是用request編程,則不需要編解碼,request 模塊會自動完成。
下面是 content-type 可能用到的 type/subtype 列表:
Type | Subtype |
---|---|
Application | application/javascript application/pdf application/xhtml+xml application/json application/ld+json application/xml application/zip application/x-www-form-urlencoded application/octet-stream : 二進制流數(shù)據(jù)(如常見的文件下載) |
Audio | audio/mpeg audio/x-ms-wma |audio audio/x-wav |
Image | image/gif image/jpeg image/png image/tiff i mage/vnd.microsoft.icon image/x-icon image/vnd.djvu image/svg+xml |
Multipart | multipart/mixed multipart/alternative multipart/related (using by MHTML (HTML mail).) multipart/form-data |
Text | text/css text/csv text/html text/plain text/xml |
Video | video/mpeg video/mp4 video/quicktime video/x-ms-wmv video/x-msvideo video/x-flv video/webm |
VND | application/vnd.oasis.opendocument.text application/vnd.oasis.opendocument.spreadsheet application/vnd.oasis.opendocument.presentation application/vnd.oasis.opendocument.graphics application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/vnd.ms-powerpoint application/vnd.openxmlformats-officedocument.presentationml.presentation application/msword application/vnd.openxmlformats-officedocument.wordprocessingml.document application/vnd.mozilla.xul+xml |
6. 用 json 做 payload
payload 就是通過http Post,get發(fā)送的數(shù)據(jù),包括請求參數(shù),文件,圖片等, 發(fā)送方可以將用json類型來準(zhǔn)備這些數(shù)據(jù),接收方用json解開。
這在Header 里約定好。如下, 但注意,header 不能是json格式。
import json import requests url = "http://www.example.com" payload = {'data': 12345, } rep = requests.post(url, data=json.dumps(payload)) print(rep.text.json())
用 data 參數(shù)提交數(shù)據(jù)時, request.body 的內(nèi)容則為 a=1&b=2 的這種形式,用 json 參數(shù)提交數(shù)據(jù)時, request.body 的內(nèi)容則為’“a”: 1, “b”: 2’ 的這種形式,如
POST /echo/post/json HTTP/1.1 Host: reqbin.com Accept: application/json Content-Type: application/json Content-Length: 52 { "Id": 12345 }
檢查響應(yīng)消息response頭部參數(shù)’content-type’,如果為 “application/json”,表示內(nèi)容為 json 格式. 可使用response對象內(nèi)置方法json()查看響應(yīng)消息的內(nèi)容
>>> r.headers['content-type'] 'application/json; charset=utf8' >>> r.json() {"success": "true", "data": { "TotalOrders": 100 } }
7. 其它requests 方法
其它請求消息, PUT與PATCH與 POST類似。 DELETE, HEAD與GET類似。
>>> requests.put('https://httpbin.org/put', data={'key':'value'}) >>> requests.delete('https://httpbin.org/delete') >>> requests.head('https://httpbin.org/get') >>> requests.patch('https://httpbin.org/patch', data={'key':'value'}) >>> requests.options('https://httpbin.org/get')
以上就是使用python requests模塊發(fā)送http請求及接收響應(yīng)的方法的詳細內(nèi)容,更多關(guān)于python requests發(fā)送http的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python實現(xiàn)字符串中字符分類及個數(shù)統(tǒng)計
這篇文章主要介紹了python實現(xiàn)字符串中字符分類及個數(shù)統(tǒng)計,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-09-09pymongo如何通過oplog獲取數(shù)據(jù)(mongodb)
使用MongoDB的oplog(操作日志)進行數(shù)據(jù)同步是高級的用法,主要用于復(fù)制和故障恢復(fù),這篇文章主要介紹了pymongo通過oplog獲取數(shù)據(jù)(mongodb),需要的朋友可以參考下2023-09-09python:pandas合并csv文件的方法(圖書數(shù)據(jù)集成)
下面小編就為大家分享一篇python:pandas合并csv文件的方法(圖書數(shù)據(jù)集成),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04python itchat實現(xiàn)微信自動回復(fù)的示例代碼
本篇文章主要介紹了python itchat實現(xiàn)微信自動回復(fù)的示例代碼,可以實現(xiàn)微信自動回復(fù),有興趣的可以了解一下2017-08-08Python中執(zhí)行JavaScript實現(xiàn)數(shù)據(jù)抓取的多種方法
JavaScript是一門強大的腳本語言,廣泛應(yīng)用于網(wǎng)頁前端開發(fā)、構(gòu)建交互式用戶界面以及處理各種客戶端端任務(wù),有時可能需要在Python環(huán)境中執(zhí)行JavaScript代碼,本文將介紹多種方法,幫助你在Python中執(zhí)行 JavaScript代碼,并提供詳盡的示例代碼,使你能夠輕松掌握這一技能2023-11-11pandas or sql計算前后兩行數(shù)據(jù)間的增值方法
下面小編就為大家分享一篇pandas or sql計算前后兩行數(shù)據(jù)間的增值方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04Django+Django-Celery+Celery的整合實戰(zhàn)
這篇文章主要介紹了Django+Django-Celery+Celery的整合實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01