http.client
— HTTP 協議客戶端¶
原始碼: Lib/http/client.py
此模組定義了實現 HTTP 和 HTTPS 協議客戶端的類。 它通常不直接使用 — 模組 urllib.request
使用它來處理使用 HTTP 和 HTTPS 的 URL。
參見
建議使用 Requests 包 來獲得更高級別的 HTTP 客戶端介面。
備註
只有在 Python 編譯時啟用了 SSL 支援(透過 ssl
模組)時,才可以使用 HTTPS 支援。
可用性:非 WASI。
此模組在 WebAssembly 上不起作用或不可用。有關更多資訊,請參閱 WebAssembly 平臺。
該模組提供以下類
- class http.client.HTTPConnection(host, port=None, [timeout, ]source_address=None, blocksize=8192)¶
HTTPConnection
例項表示與 HTTP 伺服器的單個事務。應透過傳遞主機和可選埠號來例項化它。如果未傳遞埠號,則如果主機字串的格式為host:port
,則從該字串中提取埠,否則使用預設 HTTP 埠 (80)。如果給出了可選的 *timeout* 引數,則阻塞操作(如連線嘗試)將在這麼多秒後超時(如果未給出,則使用全域性預設超時設定)。可選的 *source_address* 引數可以是一個 (host, port) 元組,用作建立 HTTP 連線的源地址。可選的 *blocksize* 引數設定傳送類檔案訊息主體的緩衝區大小(以位元組為單位)。例如,以下呼叫都建立了連線到同一主機和埠的伺服器的例項
>>> 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*。
在 3.4 版本中更改: 刪除了 *strict* 引數。不再支援 HTTP 0.9 風格的“簡單響應”。
在 3.7 版本中更改: 添加了 *blocksize* 引數。
- class http.client.HTTPSConnection(host, port=None, *, [timeout, ]source_address=None, context=None, blocksize=8192)¶
HTTPConnection
的子類,它使用 SSL 與安全伺服器進行通訊。預設埠為443
。如果指定了 *context*,則它必須是描述各種 SSL 選項的ssl.SSLContext
例項。請閱讀 安全注意事項 以獲取有關最佳實踐的更多資訊。
在 3.2 版本中更改: 添加了 *source_address*、*context* 和 *check_hostname*。
在 3.2 版本中更改: 如果可能(即,如果
ssl.HAS_SNI
為 true),此類現在支援 HTTPS 虛擬主機。在 3.4 版本中更改: 刪除了 *strict* 引數。不再支援 HTTP 0.9 風格的“簡單響應”。
在 3.4.3 版本中更改: 此類現在預設執行所有必需的證書和主機名檢查。要恢復到以前的未經驗證的行為,可以將
ssl._create_unverified_context()
傳遞給 *context* 引數。在 3.8 版本中更改: 此類現在為預設 *context* 或在傳遞帶有自定義 *context* 的 *cert_file* 時啟用 TLS 1.3
ssl.SSLContext.post_handshake_auth
。在 3.10 版本中更改: 當未給出 *context* 時,此類現在傳送帶有協議指示符
http/1.1
的 ALPN 擴充套件。自定義 *context* 應使用set_alpn_protocols()
設定 ALPN 協議。在 3.12 版本中更改: 已刪除已棄用的 *key_file*、*cert_file* 和 *check_hostname* 引數。
- class http.client.HTTPResponse(sock, debuglevel=0, method=None, url=None)¶
成功連線後返回的類的例項。不由使用者直接例項化。
在 3.4 版本中更改: 刪除了 *strict* 引數。不再支援 HTTP 0.9 風格的“簡單響應”。
此模組提供以下函式
- http.client.parse_headers(fp)¶
從表示 HTTP 請求/響應的檔案指標 *fp* 中解析標頭。該檔案必須是
BufferedIOBase
讀取器(即不是文字),並且必須提供有效的 RFC 2822 風格的標頭。此函式返回
http.client.HTTPMessage
的一個例項,該例項儲存標頭欄位,但不儲存有效負載(與HTTPResponse.msg
和http.server.BaseHTTPRequestHandler.headers
相同)。返回後,檔案指標 *fp* 已準備好讀取 HTTP 正文。備註
parse_headers()
不會解析 HTTP 訊息的起始行;它僅解析Name: value
行。該檔案必須準備好讀取這些欄位行,因此在呼叫該函式之前應已消耗第一行。
根據需要引發以下異常
- exception http.client.NotConnected¶
HTTPException
的子類。
- 異常 http.client.InvalidURL¶
是
HTTPException
的子類,如果給定的埠是非數字或為空時會引發此異常。
- 異常 http.client.UnknownProtocol¶
HTTPException
的子類。
- 異常 http.client.UnknownTransferEncoding¶
HTTPException
的子類。
- 異常 http.client.UnimplementedFileMode¶
HTTPException
的子類。
- 異常 http.client.IncompleteRead¶
HTTPException
的子類。
- 異常 http.client.ImproperConnectionState¶
HTTPException
的子類。
- 異常 http.client.CannotSendRequest¶
是
ImproperConnectionState
的子類。
- 異常 http.client.CannotSendHeader¶
是
ImproperConnectionState
的子類。
- 異常 http.client.ResponseNotReady¶
是
ImproperConnectionState
的子類。
- 異常 http.client.BadStatusLine¶
是
HTTPException
的子類。如果伺服器響應了我們不理解的 HTTP 狀態碼,則引發此異常。
- 異常 http.client.LineTooLong¶
是
HTTPException
的子類。如果在 HTTP 協議中從伺服器收到過長的行,則引發此異常。
- 異常 http.client.RemoteDisconnected¶
是
ConnectionResetError
和BadStatusLine
的子類。當嘗試讀取響應時,從連線中沒有讀取到任何資料,表明遠端端已關閉連線時,由HTTPConnection.getresponse()
引發。在 3.5 版本中新增: 之前,會引發
BadStatusLine
('')
。
此模組中定義的常量有
- http.client.HTTP_PORT¶
HTTP 協議的預設埠(始終為
80
)。
- http.client.HTTPS_PORT¶
HTTPS 協議的預設埠(始終為
443
)。
- http.client.responses¶
此字典將 HTTP 1.1 狀態碼對映到 W3C 名稱。
示例:
http.client.responses[http.client.NOT_FOUND]
為'Not Found'
。
請參閱 HTTP 狀態碼,獲取此模組中可用作常量的 HTTP 狀態碼列表。
HTTPConnection 物件¶
HTTPConnection
例項具有以下方法
- HTTPConnection.request(method, url, body=None, headers={}, *, encode_chunked=False)¶
這將使用 HTTP 請求方法 method 和請求 URI url 向伺服器傳送請求。 提供的 url 必須是絕對路徑,以符合 RFC 2616 §5.1.2 (除非連線到 HTTP 代理伺服器或使用
OPTIONS
或CONNECT
方法)。如果指定了 body,則在標頭完成後傳送指定的資料。 它可以是
str
,一個 類位元組物件,一個開啟的 檔案物件,或一個bytes
的可迭代物件。 如果 body 是一個字串,則將其編碼為 ISO-8859-1,HTTP 的預設編碼。 如果它是一個類位元組物件,則位元組按原樣傳送。 如果它是一個 檔案物件,則傳送檔案的內容;此檔案物件應至少支援read()
方法。 如果檔案物件是io.TextIOBase
的例項,則read()
方法返回的資料將編碼為 ISO-8859-1,否則read()
返回的資料將按原樣傳送。 如果 body 是一個可迭代物件,則可迭代物件的元素按原樣傳送,直到可迭代物件耗盡。headers 引數應該是要隨請求傳送的額外 HTTP 標頭的對映。 必須提供 Host 標頭 以符合 RFC 2616 §5.1.2(除非連線到 HTTP 代理伺服器或使用
OPTIONS
或CONNECT
方法)。如果 headers 既不包含 Content-Length 也不包含 Transfer-Encoding,但存在請求正文,則會自動新增這些標頭欄位之一。 如果 body 為
None
,則對於期望正文的方法(PUT
、POST
和PATCH
),Content-Length 標頭設定為0
。 如果 body 是一個字串或一個不是 檔案 的類位元組物件,則 Content-Length 標頭設定為其長度。 任何其他型別的 body (通常是檔案和可迭代物件)都將進行分塊編碼,並且會自動設定 Transfer-Encoding 標頭,而不是 Content-Length。只有在 headers 中指定了 Transfer-Encoding 時,encode_chunked 引數才相關。 如果 encode_chunked 為
False
,則 HTTPConnection 物件假定所有編碼都由呼叫程式碼處理。 如果為True
,則正文將進行分塊編碼。例如,要對
https://docs.python.club.tw/3/
執行GET
請求>>> import http.client >>> host = "docs.python.org" >>> conn = http.client.HTTPSConnection(host) >>> conn.request("GET", "/3/", headers={"Host": host}) >>> response = conn.getresponse() >>> print(response.status, response.reason) 200 OK
備註
分塊傳輸編碼已新增到 HTTP 協議版本 1.1 中。除非已知 HTTP 伺服器可以處理 HTTP 1.1,否則呼叫者必須指定 Content-Length,或者必須傳遞一個
str
或類似位元組的物件(而不是檔案)作為 body 的表示。在 3.2 版本中更改:body 現在可以是一個可迭代物件。
在 3.6 版本中更改: 如果 headers 中既沒有設定 Content-Length 也沒有設定 Transfer-Encoding,則檔案和可迭代的 body 物件現在將進行分塊編碼。添加了 encode_chunked 引數。不會嘗試確定檔案物件的 Content-Length。
- HTTPConnection.getresponse()¶
在傳送請求後呼叫此方法以從伺服器獲取響應。返回一個
HTTPResponse
例項。備註
請注意,必須讀取整個響應後才能向伺服器傳送新請求。
在 3.5 版本中更改: 如果引發
ConnectionError
或其子類,當傳送新請求時,HTTPConnection
物件將準備好重新連線。
- HTTPConnection.set_debuglevel(level)¶
設定除錯級別。預設除錯級別為
0
,表示不列印任何除錯輸出。任何大於0
的值都會導致所有當前定義的除錯輸出列印到 stdout。debuglevel
將傳遞給建立的任何新HTTPResponse
物件。在 3.1 版本中新增。
- HTTPConnection.set_tunnel(host, port=None, headers=None)¶
設定 HTTP Connect 隧道的主機和埠。這允許透過代理伺服器執行連線。
host 和 port 引數指定隧道連線的端點(即 CONNECT 請求中包含的地址,不是 代理伺服器的地址)。
headers 引數應該是一個額外的 HTTP 標頭對映,用於隨 CONNECT 請求一起傳送。
由於 HTTP/1.1 用於 HTTP CONNECT 隧道請求,根據 RFC,必須提供 HTTP
Host:
標頭,該標頭與作為 CONNECT 請求目標提供的請求目標的 authority-form 匹配。如果未透過 headers 引數提供 HTTPHost:
標頭,則會自動生成並傳輸一個。例如,要透過本地執行在埠 8080 上的 HTTPS 代理伺服器進行隧道傳輸,我們會將代理的地址傳遞給
HTTPSConnection
建構函式,並將我們最終想要到達的主機的地址傳遞給set_tunnel()
方法>>> import http.client >>> conn = http.client.HTTPSConnection("localhost", 8080) >>> conn.set_tunnel("www.python.org") >>> conn.request("HEAD","/index.html")
在 3.2 版本中新增。
在 3.12 版本中更改: HTTP CONNECT 隧道請求使用協議 HTTP/1.1,從協議 HTTP/1.0 升級。
Host:
HTTP 標頭對於 HTTP/1.1 是強制性的,因此如果 headers 引數中未提供,則會自動生成並傳輸一個。
- HTTPConnection.get_proxy_response_headers()¶
返回一個字典,其中包含從代理伺服器接收到的對 CONNECT 請求的響應的標頭。
如果未傳送 CONNECT 請求,則該方法返回
None
。在 3.12 版本中新增。
- HTTPConnection.connect()¶
連線到建立物件時指定的伺服器。預設情況下,如果客戶端尚未建立連線,則在發出請求時會自動呼叫此方法。
引發一個 審計事件
http.client.connect
,引數為self
、host
、port
。
- HTTPConnection.close()¶
關閉與伺服器的連線。
- HTTPConnection.blocksize¶
用於傳送類似檔案的訊息主體的緩衝大小(以位元組為單位)。
在 3.7 版本中新增。
作為使用上面描述的 request()
方法的替代方法,你還可以使用以下四個函式逐步傳送請求。
- HTTPConnection.putrequest(method, url, skip_host=False, skip_accept_encoding=False)¶
這應該是連線到伺服器後第一次呼叫的方法。它向伺服器傳送一行,包括 method 字串、url 字串和 HTTP 版本 (
HTTP/1.1
)。要停用自動傳送Host:
或Accept-Encoding:
標頭(例如,為了接受其他內容編碼),請將 skip_host 或 skip_accept_encoding 指定為非 False 值。
- HTTPConnection.putheader(header, argument[, ...])¶
向伺服器傳送 RFC 822 樣式的標頭。它向伺服器傳送一行,包括標頭、冒號和一個空格,以及第一個引數。如果給出了更多引數,則傳送延續行,每行包括一個製表符和一個引數。
- HTTPConnection.endheaders(message_body=None, *, encode_chunked=False)¶
向伺服器傳送一個空行,表示標頭結束。可選的 message_body 引數可用於傳遞與請求關聯的訊息主體。
如果 encode_chunked 為
True
,則 message_body 的每次迭代的結果將按照 RFC 7230 第 3.3.1 節中的規定進行分塊編碼。資料的編碼方式取決於 message_body 的型別。如果 message_body 實現了 緩衝區介面,則編碼將導致單個塊。如果 message_body 是一個collections.abc.Iterable
,則 message_body 的每次迭代都將產生一個塊。如果 message_body 是一個 檔案物件,則每次呼叫.read()
都將產生一個塊。該方法在 message_body 之後立即自動發出分塊編碼資料的結束訊號。備註
由於分塊編碼規範,迭代器主體產生的空塊將被分塊編碼器忽略。這是為了避免由於編碼錯誤而過早終止目標伺服器對請求的讀取。
3.6 版本更改: 添加了分塊編碼支援和 encode_chunked 引數。
- HTTPConnection.send(data)¶
向伺服器傳送資料。僅當呼叫了
endheaders()
方法之後,且在呼叫getresponse()
之前,才應直接使用此方法。引發帶有引數
self
,data
的審計事件http.client.send
。
HTTPResponse 物件¶
HTTPResponse
例項封裝來自伺服器的 HTTP 響應。它提供對請求頭和實體主體的訪問。響應是一個可迭代物件,並且可以在 with 語句中使用。
3.5 版本更改: 現在實現了 io.BufferedIOBase
介面,並支援其所有讀取器操作。
- HTTPResponse.read([amt])¶
讀取並返回響應主體,或最多讀取下一個 amt 位元組。
- HTTPResponse.readinto(b)¶
將響應主體的下一個 len(b) 個位元組讀取到緩衝區 b 中。返回讀取的位元組數。
3.3 版本新增。
- HTTPResponse.getheader(name, default=None)¶
返回頭 name 的值,如果沒有匹配 name 的頭,則返回 default。 如果存在多個名稱為 name 的頭,則返回所有值,用 ‘, ‘ 連線。 如果 default 是任何可迭代物件而不是單個字串,則其元素也會以逗號連線的方式返回。
- HTTPResponse.getheaders()¶
返回 (header, value) 元組的列表。
- HTTPResponse.fileno()¶
返回底層套接字的
fileno
。
- HTTPResponse.msg¶
包含響應頭的
http.client.HTTPMessage
例項。http.client.HTTPMessage
是email.message.Message
的子類。
- HTTPResponse.version¶
伺服器使用的 HTTP 協議版本。 HTTP/1.0 為 10,HTTP/1.1 為 11。
- HTTPResponse.url¶
檢索的資源的 URL,通常用於確定是否進行了重定向。
- HTTPResponse.headers¶
以
email.message.EmailMessage
例項形式存在的響應頭。
- HTTPResponse.status¶
伺服器返回的狀態程式碼。
- HTTPResponse.reason¶
伺服器返回的原因短語。
- HTTPResponse.debuglevel¶
一個除錯鉤子。如果
debuglevel
大於零,則在讀取和解析響應時,訊息將列印到標準輸出。
- HTTPResponse.closed¶
如果流已關閉,則為
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
方法從不返回任何資料。
>>> 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
方法的會話示例
>>> 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 href="https://bugs.python.org/issue12524">https://bugs.python.org/issue12524</a>'
>>> conn.close()
客戶端 HTTP PUT
請求與 POST
請求非常相似。 區別僅在於伺服器端,其中 HTTP 伺服器將允許透過 PUT
請求建立資源。 應當注意的是,透過設定適當的方法屬性,也可以在 urllib.request.Request
中處理自定義 HTTP 方法。 這是一個使用 PUT
方法的會話示例
>>> # This creates an HTTP request
>>> # with the content of BODY as the enclosed representation
>>> # for the resource https://: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 物件¶
- class http.client.HTTPMessage(email.message.Message)¶
http.client.HTTPMessage
例項儲存來自 HTTP 響應的頭。 它使用 email.message.Message
類實現。