Python HTTP 模块定义了提供 HTTP 和 HTTPS 协议客户端的类别. 在大多数程序中,HTTP 模块不是直接使用的,并且与urllib
模块俱乐部来处理 URL 连接和与 HTTP 请求的交互。
Python HTTP 客户端
在这个关于 Python HTTP 模块的文章中,我们将尝试创建连接和创建 HTTP 请求,如 GET, POST 和 PUT。
建立 HTTP 连接
我们将从HTTP模块可以做的最简单的事情开始,我们可以使用此模块轻松地创建HTTP连接。
1import http.client
2
3connection = http.client.HTTPConnection('www.python.org', 80, timeout=10)
4print(connection)
Let's see the output for this program: In this script, we connected to the URL on Port 80 with a specific timeout.
Python HTTP 获取
现在,我们将使用 HTTP 客户端从 URL 获取响应和状态,让我们看看一个代码片段:
1import http.client
2
3connection = http.client.HTTPSConnection("www.journaldev.com")
4connection.request("GET", "/")
5response = connection.getresponse()
6print("Status: {} and reason: {}".format(response.status, response.reason))
7
8connection.close()
In above script, we used a URL and checked the status with the connection object. Let's see the output for this program: Remember to close a connection once you're done with the connection object. Also, notice that we used a
HTTPSConnection
to establish the connection as the website is served over HTTPS protocol.
如何获取 SSL: CERTIFICATE_VERIFY_FAILED 错误?
当我第一次运行上述程序时,我收到与SSL证书相关的错误。
1$ python3.6 http_client.py
2Traceback (most recent call last):
3 File "http_client.py", line 4, in <module>
4 connection.request("GET", "/")
5 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1239, in request
6 self._send_request(method, url, body, headers, encode_chunked)
7 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1285, in _send_request
8 self.endheaders(body, encode_chunked=encode_chunked)
9 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1234, in endheaders
10 self._send_output(message_body, encode_chunked=encode_chunked)
11 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1026, in _send_output
12 self.send(msg)
13 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 964, in send
14 self.connect()
15 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1400, in connect
16 server_hostname=server_hostname)
17 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 401, in wrap_socket
18 context=self, session=session)
19 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 808, in init
20 self.do_handshake()
21 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 1061, in do_handshake
22 self._sslobj.do_handshake()
23 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 683, in do_handshake
24 self._sslobj.do_handshake()
25ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:748)
26$
From the output, it was clear that it has to do something with the SSL certificates. But website certificate is fine, so it has to be something with my setup. After some googling, I found that on MacOS, we need to run Install Certificates.command
file present in the Python installation directory to fix this issue. Below image shows the output produced by this command execution, it looks like it's installing latest certificates to be used when making SSL connections. Note that I got this error on Mac OS. However, on my Ubuntu system, it worked perfectly fine.
从响应中获取 Header 列表
从我们收到的响应中,标题通常还包含来自服务器发送的数据类型以及响应状态的重要信息,我们可以从响应对象本身获取标题列表。
1import http.client
2import pprint
3
4connection = http.client.HTTPSConnection("www.journaldev.com")
5connection.request("GET", "/")
6response = connection.getresponse()
7headers = response.getheaders()
8pp = pprint.PrettyPrinter(indent=4)
9pp.pprint("Headers: {}".format(headers))
Let's see the output for this program:
Python HTTP 邮件
我们可以通过 HTTP 模块将数据发送到 URL 并获得回复,这是一个示例程序:
1import http.client
2import json
3
4conn = http.client.HTTPSConnection('www.httpbin.org')
5
6headers = {'Content-type': 'application/json'}
7
8foo = {'text': 'Hello HTTP #1 **cool**, and #1!'}
9json_data = json.dumps(foo)
10
11conn.request('POST', '/post', json_data, headers)
12
13response = conn.getresponse()
14print(response.read().decode())
Let's see the output for this program: Feel free to use the HTTP Bin library to try more requests.
Python HTTP PUT 请求
当然,我们还可以使用HTTP模块执行PUT请求,我们会使用最后一个程序。
1import http.client
2import json
3
4conn = http.client.HTTPSConnection('www.httpbin.org')
5
6headers = {'Content-type': 'application/json'}
7
8foo = {'text': 'Hello HTTP #1 **cool**, and #1!'}
9json_data = json.dumps(foo)
10
11conn.request("PUT", "/put", json_data)
12response = conn.getresponse()
13print(response.status, response.reason)
Let's see the output for this program:
结论
在本课中,我们研究了可以使用http.client
进行的简单的HTTP操作,我们还可以使用 SimpleHTTPServer模块创建python http服务器。