Python HTTP客戶端請求 – GET、POST

Python的HTTP模块定义了提供HTTP和HTTPS协议的客户端部分的类。在大多数程序中,HTTP模块不是直接使用的,而是与urllib模块结合使用来处理URL连接和与HTTP请求的交互。今天我们将学习如何使用Python的HTTP客户端发送HTTP请求,然后解析响应状态并获取响应体数据。

Python的HTTP客户端

在这篇关于Python的HTTP模块的文章中,我们将尝试建立连接并发送GET、POST和PUT等HTTP请求。让我们开始吧。

建立HTTP连接

我们将从HTTP模块可以做的最简单的事情开始。我们可以使用这个模块轻松地建立HTTP连接。这是一个示例程序:

import http.client

connection = http.client.HTTPConnection('www.python.org', 80, timeout=10)
print(connection)

让我们看一下这个程序的输出:在这个脚本中,我们使用特定的超时时间连接到了端口80上的URL。

Python的HTTP GET请求

現在,我們將使用 HTTP 客戶端從 URL 獲取回應和狀態。讓我們看一下代碼片段:

import http.client

connection = http.client.HTTPSConnection("www.journaldev.com")
connection.request("GET", "/")
response = connection.getresponse()
print("Status: {} and reason: {}".format(response.status, response.reason))

connection.close()

在上面的腳本中,我們使用了一個 URL,並使用連接對象檢查了狀態。讓我們看一下此程序的輸出:在使用完連接對象後,記得關閉連接。同時,請注意,我們使用了 HTTPSConnection 來建立連接,因為該網站是通過 HTTPS 協議提供服務的。

獲取 SSL: CERTIFICATE_VERIFY_FAILED 錯誤?

當我第一次執行上面的程序時,我遇到了與 SSL 憑證相關的以下錯誤。

$ python3.6 http_client.py 
Traceback (most recent call last):
  File "http_client.py", line 4, in <module>
    connection.request("GET", "/")
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1239, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1285, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1234, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1026, in _send_output
    self.send(msg)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 964, in send
    self.connect()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1400, in connect
    server_hostname=server_hostname)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 401, in wrap_socket
    context=self, session=session)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 808, in init
    self.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 1061, in do_handshake
    self._sslobj.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 683, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:748)
$ 

從輸出中可以明顯看出,這與 SSL 憑證有關。但網站證書是正常的,所以問題應該是出在我的設置上。經過一些搜索,我發現在 MacOS 上,我們需要運行 Python 安裝目錄中的 Install Certificates.command 文件來解決此問題。下圖顯示了此命令執行產生的輸出,看起來它正在安裝最新的憑證以在進行 SSL 連接時使用。請注意,我在 Mac OS 上遇到了此錯誤。然而,在我的 Ubuntu 系統上,它運行得非常正常。

Python HTTP Client Ubuntu

從響應中獲取標頭列表

從我們收到的響應中,標頭通常也包含有關從服務器返回的數據類型和響應狀態的重要信息。我們可以從響應對象本身獲取標頭列表。讓我們看一下這個程式碼片段,這是上一個程式的一個稍作修改的版本:

import http.client
import pprint

connection = http.client.HTTPSConnection("www.journaldev.com")
connection.request("GET", "/")
response = connection.getresponse()
headers = response.getheaders()
pp = pprint.PrettyPrinter(indent=4)
pp.pprint("Headers: {}".format(headers))

讓我們看看這個程式的輸出:

Python HTTP POST

我們也可以使用HTTP模塊將數據POST到URL,並獲取響應。這是一個示例程式:

import http.client
import json

conn = http.client.HTTPSConnection('www.httpbin.org')

headers = {'Content-type': 'application/json'}

foo = {'text': 'Hello HTTP #1 **cool**, and #1!'}
json_data = json.dumps(foo)

conn.request('POST', '/post', json_data, headers)

response = conn.getresponse()
print(response.read().decode())

讓我們看看這個程式的輸出: 歡迎使用HTTP Bin庫嘗試更多請求。

Python HTTP PUT 請求

當然,我們也可以使用 HTTP 模塊本身執行 PUT 請求。我們將使用上一個程序本身。讓我們看一下代碼片段:

import http.client
import json

conn = http.client.HTTPSConnection('www.httpbin.org')

headers = {'Content-type': 'application/json'}

foo = {'text': 'Hello HTTP #1 **cool**, and #1!'}
json_data = json.dumps(foo)


conn.request("PUT", "/put", json_data)
response = conn.getresponse()
print(response.status, response.reason)

讓我們看一下此程序的輸出:

結論

在這課程中,我們學習了使用 http.client 可以執行的簡單 HTTP 操作。我們還可以使用 SimpleHTTPServer 模塊創建 Python HTTP 服務器。參考文獻:API 文檔

Source:
https://www.digitalocean.com/community/tutorials/python-http-client-request-get-post