Python HTTP 客户端请求 - GET、POST

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: python http connection 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. python ssl CERTIFICATE_VERIFY_FAILED fix Note that I got this error on Mac OS. However, on my Ubuntu system, it worked perfectly fine.

Python HTTP Client Ubuntu

从响应中获取 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 request headers

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: python http post 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: python http request, python http put example

结论

在本课中,我们研究了可以使用http.client进行的简单的HTTP操作,我们还可以使用 SimpleHTTPServer模块创建python http服务器。

Published At
Categories with 技术
Tagged with
comments powered by Disqus