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

Python HTTP 客户端

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

建立 HTTP 连接

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

import http.client

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

让我们看看这个程序的输出:python http 连接在这个脚本中,我们使用特定的超时时间连接到端口 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 连接时要使用的最新证书。 python ssl CERTIFICATE_VERIFY_FAILED fix请注意,我在 Mac OS 上收到此错误。但是,在我的 Ubuntu 系统上,它运行良好。

Python HTTP 客户端 Ubuntu

Python HTTP 客户端 Ubuntu

从 Response 中获取 Header 列表

从我们收到的响应中,标头通常还包含有关从服务器发送回的数据类型以及响应状态的重要信息。我们可以从响应对象本身获得一个标头列表。让我们看一个代码片段,它是最后一个程序的小修改版本:

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请求头

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())

让我们看看这个程序的输出:python http post随意使用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)

让我们看看这个程序的输出:python http请求,python http put示例

结论

在本课中,我们学习了可以使用http.client完成的简单 HTTP 操作。我们还可以使用SimpleHTTPServer模块创建 python http 服务器。参考:API Doc

Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐