http.client
--- HTTP 協(xié)議客戶端?
源代碼: Lib/http/client.py
這個模塊定義了實(shí)現(xiàn) HTTP 和 HTTPS 協(xié)議客戶端的類。 它通常不直接使用 --- 模塊 urllib.request
用它來處理使用 HTTP 和 HTTPS 的 URL。
參見
對于更高級別的 HTTP 客戶端接口,建議使用 Requests 。
備注
HTTPS 支持僅在編譯 Python 時啟用了 SSL 支持的情況下(通過 ssl
模塊)可用。
該模塊支持以下類:
- class http.client.HTTPConnection(host, port=None, [timeout, ]source_address=None, blocksize=8192)?
HTTPConnection
的實(shí)例代表與 HTTP 的一個連接事務(wù)。 它的實(shí)例化應(yīng)當(dāng)傳入一個主機(jī)和可選的端口號。 如果沒有傳入端口號,如果主機(jī)字符串的形式為主機(jī):端口
則會從中提取端口,否則將使用默認(rèn)的 HTTP 端口(80)。 如果給出了可選的 timeout 參數(shù),則阻塞操作(例如連接嘗試)將在指定的秒數(shù)之后超時(如果未給出,則使用全局默認(rèn)超時設(shè)置)。 可選的 source_address 參數(shù)可以為一個 (主機(jī), 端口) 元組,用作進(jìn)行 HTTP 連接的源地址。 可選的 blocksize 參數(shù)可以字節(jié)為單位設(shè)置緩沖區(qū)的大小,用來發(fā)送文件類消息體。舉個例子,以下調(diào)用都是創(chuàng)建連接到同一主機(jī)和端口的服務(wù)器的實(shí)例:
>>> h1 = http.client.HTTPConnection('www.python.org') >>> h2 = http.client.HTTPConnection('www.python.org:80') >>> h3 = http.client.HTTPConnection('www.python.org', 80) >>> h4 = http.client.HTTPConnection('www.python.org', 80, timeout=10)
在 3.2 版更改: 添加了*source_address* 參數(shù)
在 3.4 版更改: 刪除了 strict 參數(shù),不再支持 HTTP 0.9 風(fēng)格的“簡單響應(yīng)”。
在 3.7 版更改: 添加了 blocksize 參數(shù)。
- class http.client.HTTPSConnection(host, port=None, key_file=None, cert_file=None, [timeout, ]source_address=None, *, context=None, check_hostname=None, blocksize=8192)?
HTTPConnection
的子類,使用 SSL 與安全服務(wù)器進(jìn)行通信。 默認(rèn)端口為443
。 如果指定了 context,它必須為一個描述 SSL 各選項(xiàng)的ssl.SSLContext
實(shí)例。請參閱 安全考量 了解有關(guān)最佳實(shí)踐的更多信息。
在 3.2 版更改: 添加了 source_address, context 和 check_hostname。
在 3.2 版更改: 這個類目前會在可能的情況下(即如果
ssl.HAS_SNI
為真值)支持 HTTPS 虛擬主機(jī)。在 3.4 版更改: 刪除了 strict 參數(shù),不再支持 HTTP 0.9 風(fēng)格的“簡單響應(yīng)”。
在 3.4.3 版更改: 目前這個類在默認(rèn)情況下會執(zhí)行所有必要的證書和主機(jī)檢查。 要回復(fù)到先前的非驗(yàn)證行為,可以將
ssl._create_unverified_context()
傳遞給 context 參數(shù)。在 3.8 版更改: 該類現(xiàn)在對于默認(rèn)的 context 或在傳入 cert_file 并附帶自定義 context 時會啟用 TLS 1.3
ssl.SSLContext.post_handshake_auth
。在 3.10 版更改: 現(xiàn)在,若未給出 context,則會發(fā)送一個帶有協(xié)議指示器
http/1.1
的ALPN 擴(kuò)展。自定義 context 應(yīng)用set_alpn_protocol()
設(shè)置 ALPN 協(xié)議。3.6 版后已移除: key_file 和 cert_file 已棄用并轉(zhuǎn)而推薦 context。 請改用
ssl.SSLContext.load_cert_chain()
或讓ssl.create_default_context()
為你選擇系統(tǒng)所信任的 CA 證書。check_hostname 參數(shù)也已棄用;應(yīng)當(dāng)改用 context 的
ssl.SSLContext.check_hostname
屬性。
- class http.client.HTTPResponse(sock, debuglevel=0, method=None, url=None)?
在成功連接后返回類的實(shí)例,而不是由用戶直接實(shí)例化。
在 3.4 版更改: 刪除了 strict 參數(shù),不再支持HTTP 0.9 風(fēng)格的“簡單響應(yīng)”。
這個模塊定義了以下函數(shù):
- http.client.parse_headers(fp)?
從文件指針 fp 中解析頭部信息,該文件代表 HTTP 請求/響應(yīng)。該文件必須是
BufferedIOBase
reader 對象(即不是文本),并且必須提供符合 RFC 2822 格式的頭部。該函數(shù)返回
http.client.HTTPMessage
的實(shí)例,帶有頭部各個字段,但不帶正文數(shù)據(jù)(與HTTPResponse.msg
和http.server.BaseHTTPRequestHandler.headers
一樣)。返回之后,文件指針 fp 已為讀取 HTTP 正文做好準(zhǔn)備了。備注
parse_headers()
不會解析 HTTP 消息的開始行;只會解析各Name: value
行。文件必須為讀取這些字段做好準(zhǔn)備,所以在調(diào)用該函數(shù)之前,第一行應(yīng)該已經(jīng)被讀取過了。
下列異??梢赃m當(dāng)?shù)乇灰l(fā):
- exception http.client.NotConnected?
HTTPException
的一個子類。
- exception http.client.InvalidURL?
HTTPException
的一個子類,如果給出了一個非數(shù)字或?yàn)榭罩档亩丝诰蜁灰l(fā)。
- exception http.client.UnknownProtocol?
HTTPException
的一個子類。
- exception http.client.UnknownTransferEncoding?
HTTPException
的一個子類。
- exception http.client.UnimplementedFileMode?
HTTPException
的一個子類。
- exception http.client.IncompleteRead?
HTTPException
的一個子類。
- exception http.client.ImproperConnectionState?
HTTPException
的一個子類。
- exception http.client.CannotSendRequest?
ImproperConnectionState
的一個子類。
- exception http.client.CannotSendHeader?
ImproperConnectionState
的一個子類。
- exception http.client.ResponseNotReady?
ImproperConnectionState
的一個子類。
- exception http.client.BadStatusLine?
HTTPException
的一個子類。 如果服務(wù)器反饋了一個我們不理解的 HTTP 狀態(tài)碼就會被引發(fā)。
- exception http.client.LineTooLong?
HTTPException
的一個子類。 如果在 HTTP 協(xié)議中從服務(wù)器接收到過長的行就會被引發(fā)。
- exception http.client.RemoteDisconnected?
ConnectionResetError
和BadStatusLine
的一個子類。 當(dāng)嘗試讀取響應(yīng)時的結(jié)果是未從連接讀取到數(shù)據(jù)時由HTTPConnection.getresponse()
引發(fā),表明遠(yuǎn)端已關(guān)閉連接。3.5 新版功能: 在此之前引發(fā)的異常為
BadStatusLine
('')
。
此模塊中定義的常量為:
- http.client.HTTP_PORT?
HTTP 協(xié)議默認(rèn)的端口號 (總是
80
)。
- http.client.HTTPS_PORT?
HTTPS 協(xié)議默認(rèn)的端口號 (總是
443
)。
- http.client.responses?
這個字典把 HTTP 1.1 狀態(tài)碼映射到 W3C 名稱。
例如:
http.client.responses[http.client.NOT_FOUND]
是'NOT FOUND
(未發(fā)現(xiàn))。
本模塊中可用的 HTTP 狀態(tài)碼常量可以參見 HTTP 狀態(tài)碼 。
HTTPConnection 對象?
HTTPConnection
實(shí)例擁有以下方法:
- HTTPConnection.request(method, url, body=None, headers={}, *, encode_chunked=False)?
這會使用 HTTP 請求方法 method 和選擇器 url 向服務(wù)器發(fā)送請求。
如果給定 body,那么給定的數(shù)據(jù)會在信息頭完成之后發(fā)送。它可能是一個
字符串
,一個 bytes-like object,一個打開的 file object,或者bytes
迭代器。如果 body 是字符串,它會按 HTTP 默認(rèn)的 ISO-8859-1 編碼。如果是一個字節(jié)類對象,它會按原樣發(fā)送。如果是 file object,文件的內(nèi)容會被發(fā)送,這個文件對象應(yīng)該至少支持``read()`` 方法。如果這個文件對象是一個io.TextIOBase
實(shí)例,由read()
方法返回的數(shù)據(jù)會按 ISO-8859-1 編碼,否則由read()
方法返回的數(shù)據(jù)會按原樣發(fā)送。如果 body 是一個迭代器,迭代器中的元素會被發(fā)送,直到迭代器耗盡。headers 參數(shù)應(yīng)是額外的隨請求發(fā)送的 HTTP 信息頭的字典。
如果 headers 既不包含 Content-Length 也沒有 Transfer-Encoding,但存在請求正文,那么這些頭字段中的一個會自動設(shè)定。如果 body 是
None
,那么對于要求正文的方法 (PUT
,POST
,和PATCH
),Content-Length 頭會被設(shè)為0
。如果 body 是字符串或者類似字節(jié)的對象,并且也不是 文件,Content-Length 頭會設(shè)為正文的長度。任何其他類型的 body (一般是文件或迭代器)會按塊編碼,這時會自動設(shè)定 Transfer-Encoding 頭以代替 Content-Length。在 headers 中指定 Transfer-Encoding 時, encode_chunked 是唯一相關(guān)的參數(shù)。如果 encode_chunked 為
False
,HTTPConnection 對象會假定所有的編碼都由調(diào)用代碼處理。如果為True
,正文會按塊編碼。備注
HTTP 協(xié)議在 1.1 版中添加了塊傳輸編碼。除非明確知道 HTTP 服務(wù)器可以處理 HTTP 1.1,調(diào)用者要么必須指定 Content-Length,要么必須傳入
str
或字節(jié)類對象,注意該對象不能是表達(dá) body 的文件。3.2 新版功能: body 現(xiàn)在可以是可迭代對象了。
在 3.6 版更改: 如果 Content-Length 和 Transfer-Encoding 都沒有在 headers 中設(shè)置,文件和可迭代的 body 對象現(xiàn)在會按塊編碼。添加了 encode_chunked 參數(shù)。不會嘗試去確定文件對象的 Content-Length。
- HTTPConnection.getresponse()?
應(yīng)當(dāng)在發(fā)送一個請求從服務(wù)器獲取響應(yīng)時被調(diào)用。 返回一個
HTTPResponse
的實(shí)例。備注
請注意你必須在讀取了整個響應(yīng)之后才能向服務(wù)器發(fā)送新的請求。
在 3.5 版更改: 如果引發(fā)了
ConnectionError
或其子類,HTTPConnection
對象將在發(fā)送新的請求時準(zhǔn)備好重新連接。
- HTTPConnection.set_debuglevel(level)?
設(shè)置調(diào)試等級。 默認(rèn)的調(diào)試等級為
0
,意味著不會打印調(diào)試輸出。 任何大于0
的值將使得所有當(dāng)前定義的調(diào)試輸出被打印到 stdout。debuglevel
會被傳給任何新創(chuàng)建的HTTPResponse
對象。3.1 新版功能.
- HTTPConnection.set_tunnel(host, port=None, headers=None)?
為 HTTP 連接隧道設(shè)置主機(jī)和端口。 這將允許通過代理服務(wù)器運(yùn)行連接。
host 和 port 參數(shù)指明隧道連接的位置(即 CONNECT 請求所包含的地址,而 不是 代理服務(wù)器的地址)。
headers 參數(shù)應(yīng)為一個隨 CONNECT 請求發(fā)送的額外 HTTP 標(biāo)頭的映射。
例如,要通過一個運(yùn)行于本機(jī) 8080 端口的 HTTPS 代理服務(wù)器隧道,我們應(yīng)當(dāng)向
HTTPSConnection
構(gòu)造器傳入代理的地址,并將我們最終想要訪問的主機(jī)地址傳給set_tunnel()
方法:>>> import http.client >>> conn = http.client.HTTPSConnection("localhost", 8080) >>> conn.set_tunnel("www.python.org") >>> conn.request("HEAD","/index.html")
3.2 新版功能.
- HTTPConnection.connect()?
當(dāng)對象被創(chuàng)建后連接到指定的服務(wù)器。 默認(rèn)情況下,如果客戶端還未建立連接,此函數(shù)會在發(fā)送請求時自動被調(diào)用。
觸發(fā) 音頻事件
http.client.connect
,帶有self
、host
、port
參數(shù)。
- HTTPConnection.close()?
關(guān)閉到服務(wù)器的連接。
- HTTPConnection.blocksize?
用于發(fā)送文件類消息體的緩沖區(qū)大小。
3.7 新版功能.
作為對使用上述 request()
方法的替代同,你也可以通過使用下面的四個函數(shù),分步驟發(fā)送請的請求。
- HTTPConnection.putrequest(method, url, skip_host=False, skip_accept_encoding=False)?
應(yīng)為連接服務(wù)器之后首先調(diào)用的函數(shù)。將向服務(wù)器發(fā)送一行數(shù)據(jù),包含 method 字符串、url 字符串和 HTTP 版本(
HTTP/1.1
)。若要禁止自動發(fā)送Host:
或Accept-Encoding:
頭部信息(比如需要接受其他編碼格式的內(nèi)容),請將 skip_host 或 skip_accept_encoding 設(shè)為非 False 值。
- HTTPConnection.putheader(header, argument[, ...])?
向服務(wù)器發(fā)送一個 RFC 822 格式的頭部。將向服務(wù)器發(fā)送一行由頭、冒號和空格以及第一個參數(shù)組成的數(shù)據(jù)。 如果還給出了其他參數(shù),將在后續(xù)行中發(fā)送,每行由一個制表符和一個參數(shù)組成。
- HTTPConnection.endheaders(message_body=None, *, encode_chunked=False)?
向服務(wù)器發(fā)送一個空行,表示頭部文件結(jié)束。可選的 message_body 參數(shù)可用于傳入一個與請求相關(guān)的消息體。
如果 encode_chunked 為
True
,則對 message_body 的每次迭代結(jié)果將依照 RFC 7230 3.3.1 節(jié)的規(guī)范進(jìn)行分塊編碼。數(shù)據(jù)如何編碼取決于 message_body 的類型。 如果 message_body 實(shí)現(xiàn)了 buffer 接口,編碼將生成一個數(shù)據(jù)塊。如果 message_body 是collections.abc.Iterable
,則 message_body 的每次迭代都會產(chǎn)生一個塊。 如果 message_body 為 file object,那么每次調(diào)用.read()
都會產(chǎn)生一個數(shù)據(jù)塊。在 message_body 結(jié)束后,本方法立即會自動標(biāo)記分塊編碼數(shù)據(jù)的結(jié)束。備注
由于分塊編碼的規(guī)范要求,迭代器本身產(chǎn)生的空塊將被分塊編碼器忽略。這是為了避免目標(biāo)服務(wù)器因錯誤編碼而過早終止對請求的讀取。
3.6 新版功能: 支持分塊編碼。加入了 encode_chunked 參數(shù)。
- HTTPConnection.send(data)?
發(fā)送數(shù)據(jù)到服務(wù)器。本函數(shù)只應(yīng)在調(diào)用
endheaders()
方法之后且調(diào)用getresponse()
之前直接調(diào)用。觸發(fā) 音頻事件
http.client.send
,參數(shù)為self
、data
。
HTTPResponse 對象?
HTTPResponse
實(shí)例封裝了來自服務(wù)器的 HTTP 響應(yīng)。通過它可以訪問請求頭和響應(yīng)體。響應(yīng)是可迭代對象,可在 with 語句中使用。
在 3.5 版更改: 現(xiàn)在已實(shí)現(xiàn)了 io.BufferedIOBase
接口,并且支持所有的讀取操作。
- HTTPResponse.read([amt])?
讀取并返回響應(yīng)體,或后續(xù) amt 個字節(jié)。
- HTTPResponse.readinto(b)?
讀取響應(yīng)體的后續(xù) len(b) 個字節(jié)到緩沖區(qū) b。返回讀取的字節(jié)數(shù)。
3.3 新版功能.
- HTTPResponse.getheader(name, default=None)?
返回頭部信息中的 name 值,如果沒有與 name 匹配的字段,則返回*default*。如果名為 name 的字段不止一個,則返回所有字段,中間用 ', ' 連接。 如果 'default' 不是單個字符串,而是其他可迭代對象,則其元素同樣以逗號連接并返回。
- HTTPResponse.getheaders()?
返回 (header, value) 元組構(gòu)成的列表。
- HTTPResponse.fileno()?
返回底層套接字的
fileno
。
- HTTPResponse.msg?
包含響應(yīng)頭的
http.client.HTTPMessage
實(shí)例。http.client.HTTPMessage
是email.message
的子類。
- HTTPResponse.version?
服務(wù)器采用的 HTTP 協(xié)議版本。10 代表 HTTP/1.0,11 代表 HTTP/1.1。
- HTTPResponse.url?
已讀取資源的 URL,通常用于確定是否進(jìn)行了重定向。
- HTTPResponse.headers?
響應(yīng)的頭部信息,形式為
email.message.EmailMessage
的實(shí)例。
- HTTPResponse.status?
由服務(wù)器返回的狀態(tài)碼。
- HTTPResponse.reason?
服務(wù)器返回的原因短語。
- HTTPResponse.debuglevel?
一個調(diào)試鉤子。如果
debuglevel
大于零,狀態(tài)信息將在讀取和解析響應(yīng)數(shù)據(jù)時打印輸出到 stdout。
- HTTPResponse.closed?
如果流被關(guān)閉,則為``True``。
例子?
下面是使用 GET
方法的會話示例:
>>> import http.client
>>> conn = http.client.HTTPSConnection("www.python.org")
>>> conn.request("GET", "/")
>>> r1 = conn.getresponse()
>>> print(r1.status, r1.reason)
200 OK
>>> data1 = r1.read() # This will return entire content.
>>> # The following example demonstrates reading data in chunks.
>>> conn.request("GET", "/")
>>> r1 = conn.getresponse()
>>> while chunk := r1.read(200):
... print(repr(chunk))
b'<!doctype html>\n<!--[if"...
...
>>> # Example of an invalid request
>>> conn = http.client.HTTPSConnection("docs.python.org")
>>> conn.request("GET", "/parrot.spam")
>>> r2 = conn.getresponse()
>>> print(r2.status, r2.reason)
404 Not Found
>>> data2 = r2.read()
>>> conn.close()
以下是使用 HEAD
方法的會話示例。 請注意,HEAD
方法從不返回任何數(shù)據(jù)。
>>> import http.client
>>> conn = http.client.HTTPSConnection("www.python.org")
>>> conn.request("HEAD", "/")
>>> res = conn.getresponse()
>>> print(res.status, res.reason)
200 OK
>>> data = res.read()
>>> print(len(data))
0
>>> data == b''
True
下面是用 POST
發(fā)送請求的會話示例:
>>> import http.client, urllib.parse
>>> params = urllib.parse.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'})
>>> headers = {"Content-type": "application/x-www-form-urlencoded",
... "Accept": "text/plain"}
>>> conn = http.client.HTTPConnection("bugs.python.org")
>>> conn.request("POST", "", params, headers)
>>> response = conn.getresponse()
>>> print(response.status, response.reason)
302 Found
>>> data = response.read()
>>> data
b'Redirecting to <a
>>> conn.close()
在客戶端, HTTP PUT
請求與 POST
請求非常相似。區(qū)別只在于服務(wù)器端,HTTP 服務(wù)器將允許通過 PUT
請求創(chuàng)建資源。應(yīng)該注意的是,自定義的 HTTP 方法也可以在 urllib.request.Request
中通過設(shè)置適當(dāng)?shù)姆椒▽傩詠磉M(jìn)行處理。下面是一個會話示例,演示了如何利用 http.client 發(fā)送 PUT
請求。
>>> # This creates an HTTP message
>>> # with the content of BODY as the enclosed representation
>>> # for the resource http://localhost:8080/file
...
>>> import http.client
>>> BODY = "***filecontents***"
>>> conn = http.client.HTTPConnection("localhost", 8080)
>>> conn.request("PUT", "/file", BODY)
>>> response = conn.getresponse()
>>> print(response.status, response.reason)
200, OK
HTTPMessage 對象?
http.client.HTTPMessage
的實(shí)例存有 HTTP 響應(yīng)的頭部信息。利用 email.message.Message
類實(shí)現(xiàn)。