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