http.client ---HTTP协议客户端

源代码: Lib/http/client.py


此模块定义实现HTTP和HTTPS协议客户端的类。通常不直接使用——模块 urllib.request 使用它来处理使用HTTP和HTTPS的URL。

参见

这个 Requests package 建议用于更高级别的HTTP客户端接口。

注解

只有使用SSL支持编译了python(通过 ssl 模块)。

该模块提供以下类:

class http.client.HTTPConnection(host, port=None, [timeout, ]source_address=None, blocksize=8192)

HTTPConnection 实例表示一个与HTTP服务器的事务。它应该通过传递一个主机和可选的端口号来实例化。如果没有传递端口号,则从主机字符串中提取端口(如果该端口具有 host:port ,否则将使用默认的HTTP端口(80)。如果可选 timeout 给定参数后,阻塞操作(如连接尝试)将在该秒数后超时(如果未给定,则使用全局默认超时设置)。可选的 source_address 参数可以是(主机、端口)的元组,用作建立HTTP连接的源地址。可选的 块状 参数设置用于发送类似消息正文的文件的缓冲区大小(以字节为单位)。

例如,以下调用所有连接到同一主机和端口上的服务器的创建实例:

>>> h1 = http.client.HTTPConnection('www.python.org')
>>> h2 = http.client.HTTPConnection('www.python.org:80')
>>> h3 = http.client.HTTPConnection('www.python.org', 80)
>>> h4 = http.client.HTTPConnection('www.python.org', 80, timeout=10)

在 3.2 版更改: source_address 加入。

在 3.4 版更改: 这个 strict 参数已删除。不再支持HTTP 0.9样式的“简单响应”。

在 3.7 版更改: 块状 已添加参数。

class http.client.HTTPSConnection(host, port=None, key_file=None, cert_file=None, [timeout, ]source_address=None, *, context=None, check_hostname=None, blocksize=8192)

一个子类 HTTPConnection 它使用SSL与安全服务器通信。默认端口为 443 . 如果 context 是指定的,它必须是 ssl.SSLContext 描述各种SSL选项的实例。

请阅读 安全注意事项 有关最佳实践的更多信息。

在 3.2 版更改: source_addresscontextcheck_hostname 加入。

在 3.2 版更改: 如果可能的话,这个类现在支持HTTPS虚拟主机(也就是说,如果 ssl.HAS_SNI 是真的)。

在 3.4 版更改: 这个 strict 参数已删除。不再支持HTTP 0.9样式的“简单响应”。

在 3.4.3 版更改: 这个类现在默认执行所有必要的证书和主机名检查。恢复到上一个未验证的行为 ssl._create_unverified_context() 可以传递给 context 参数。

在 3.8 版更改: 此类现在启用了TLS 1.3 ssl.SSLContext.post_handshake_auth 默认 语境 或者什么时候 cert_file 通过自定义 语境 .

在 3.10 版更改: 此类现在发送带有协议指示符的ALPN扩展 http/1.1 当没有 上下文 给出了。自定义 上下文 应将ALPN协议设置为 set_alpn_protocol()

3.6 版后已移除: key_filecert_file 被否决,赞成 context . 请使用 ssl.SSLContext.load_cert_chain() 相反,还是让 ssl.create_default_context() 为您选择系统的可信CA证书。

这个 check_hostname 参数也已弃用;参数 ssl.SSLContext.check_hostname 属性 context 应该改为使用。

class http.client.HTTPResponse(sock, debuglevel=0, method=None, url=None)

成功连接后返回其实例的类。不是由用户直接实例化的。

在 3.4 版更改: 这个 strict 参数已删除。不再支持HTTP 0.9样式的“简单响应”。

此模块提供以下功能:

http.client.parse_headers(fp)

从文件指针分析头 fp 表示HTTP请求/响应。文件必须是 BufferedIOBase 读卡器(即非文本),必须提供有效的 RFC 2822 样式标题。

此函数返回 http.client.HTTPMessage 它保存头字段,但没有有效负载(与 HTTPResponse.msghttp.server.BaseHTTPRequestHandler.headers )返回后,文件指针 fp 准备读取HTTP主体。

注解

parse_headers() 不分析HTTP消息的起始行;它只分析 Name: value 线。文件必须准备好读取这些字段行,因此在调用函数之前应该已经使用了第一行。

视情况提出以下例外情况:

exception http.client.HTTPException

此模块中其他异常的基类。它是 Exception .

exception http.client.NotConnected

一个子类 HTTPException .

exception http.client.InvalidURL

一个子类 HTTPException ,在给定端口且不是数字或为空时引发。

exception http.client.UnknownProtocol

一个子类 HTTPException .

exception http.client.UnknownTransferEncoding

一个子类 HTTPException .

exception http.client.UnimplementedFileMode

一个子类 HTTPException .

exception http.client.IncompleteRead

一个子类 HTTPException .

exception http.client.ImproperConnectionState

一个子类 HTTPException .

exception http.client.CannotSendRequest

一个子类 ImproperConnectionState .

exception http.client.CannotSendHeader

一个子类 ImproperConnectionState .

exception http.client.ResponseNotReady

一个子类 ImproperConnectionState .

exception http.client.BadStatusLine

一个子类 HTTPException .如果服务器用我们不理解的HTTP状态代码响应,则引发。

exception http.client.LineTooLong

一个子类 HTTPException . 如果在HTTP协议中从服务器接收到过长的行,则引发。

exception http.client.RemoteDisconnected

一个子类 ConnectionResetErrorBadStatusLine . 由提高 HTTPConnection.getresponse() 当尝试读取响应导致没有从连接中读取数据时,表示远程端已关闭连接。

3.5 新版功能: 以前, BadStatusLine ('') 提高了。

此模块中定义的常量为:

http.client.HTTP_PORT

HTTP协议的默认端口(始终 80

http.client.HTTPS_PORT

HTTPS协议的默认端口(始终 443

http.client.responses

此字典将HTTP 1.1状态代码映射到W3C名称。

例子: http.client.responses[http.client.NOT_FOUND]'Not Found' .

状态代码 获取此模块中可用作常量的HTTP状态代码列表。

httpConnection对象

HTTPConnection 实例具有以下方法:

HTTPConnection.request(method, url, body=None, headers={}, *, encode_chunked=False)

这将使用HTTP请求方法向服务器发送请求 方法 以及选择器 url .

如果 body 指定,指定的数据在头完成后发送。它可能是一个 str ,A bytes-like object 一个开放的 file objectbytes . 如果 body 是一个字符串,它被编码为ISO-8859-1,HTTP的默认值。如果它是一个类似于对象的字节,则按原样发送字节。如果是一个 file object ,将发送文件的内容;此文件对象至少应支持 read() 方法。如果文件对象是 io.TextIOBase ,返回的数据 read() 方法将被编码为ISO-8859-1,否则返回的数据 read() 按原样发送。如果 body 是一个iterable,iterable的元素按原样发送,直到iterable耗尽。

这个 headers 参数应该是与请求一起发送的额外HTTP头的映射。

如果 headers 既不包含内容长度也不包含传输编码,但有一个请求主体,将自动添加其中一个头字段。如果 bodyNone ,内容长度标题设置为 0 对于需要主体的方法 (PUTPOSTPATCH )如果 body 是一个字符串或类似字节的对象,它不是 file ,Content-Length头被设置为其长度。任何其他类型的 body (文件和iterables通常)将进行块编码,传输编码头将自动设置,而不是内容长度。

这个 encode_chunked 只有在中指定了传输编码时,参数才相关。 headers . 如果 encode_chunkedFalse ,httpConnection对象假定所有编码都由调用代码处理。如果是 True 将对正文进行块编码。

注解

分块传输编码已添加到HTTP协议版本1.1中。除非知道HTTP服务器可以处理HTTP 1.1,否则调用方必须指定内容长度,或者必须传递 str 或者类似对象的字节,它也不是作为主体表示的文件。

3.2 新版功能: body 现在可以是一个不可更改的。

在 3.6 版更改: 如果在中既没有设置内容长度也没有设置传输编码 headers ,文件和ITerable body 对象现在是块编码的。这个 encode_chunked 已添加参数。未尝试确定文件对象的内容长度。

HTTPConnection.getresponse()

应在发送请求以从服务器获取响应后调用。返回一个 HTTPResponse 实例。

注解

请注意,在向服务器发送新请求之前,您必须已经阅读了整个响应。

在 3.5 版更改: 如果A ConnectionError 或者子类被引发, HTTPConnection 发送新请求时,对象将准备重新连接。

HTTPConnection.set_debuglevel(level)

设置调试级别。默认调试级别为 0 ,表示不打印调试输出。任何大于 0 将导致当前定义的所有调试输出打印到stdout。这个 debuglevel 传递给任何新的 HTTPResponse 创建的对象。

3.1 新版功能.

HTTPConnection.set_tunnel(host, port=None, headers=None)

为HTTP连接隧道设置主机和端口。这允许通过代理服务器运行连接。

主机和端口参数指定隧道连接的端点(即连接请求中包含的地址, not 代理服务器的地址)。

headers参数应该是与connect请求一起发送的额外HTTP头的映射。

例如,要通过在端口8080上本地运行的HTTPS代理服务器进行隧道传输,我们将把代理的地址传递给 HTTPSConnection 构造器,以及我们最终想要到达的主机的地址 set_tunnel() 方法:

>>> import http.client
>>> conn = http.client.HTTPSConnection("localhost", 8080)
>>> conn.set_tunnel("www.python.org")
>>> conn.request("HEAD","/index.html")

3.2 新版功能.

HTTPConnection.connect()

连接到创建对象时指定的服务器。默认情况下,如果客户机还没有连接,则在发出请求时自动调用此函数。

HTTPConnection.close()

关闭与服务器的连接。

HTTPConnection.blocksize

以字节为单位的缓冲区大小,用于发送类似消息正文的文件。

3.7 新版功能.

作为使用 request() 方法如上所述,您还可以使用下面的四个函数逐步发送请求。

HTTPConnection.putrequest(method, url, skip_host=False, skip_accept_encoding=False)

这应该是连接到服务器之后的第一个调用。它向服务器发送一条由 方法 字符串, url 字符串和HTTP版本 (HTTP/1.1 )禁用自动发送 Host:Accept-Encoding: 头(例如接受其他内容编码),指定 skip_hostskip_accept_encoding 具有非假值。

HTTPConnection.putheader(header, argument[, ...])

发送一个 RFC 822 -服务器的样式头。它向服务器发送一行,由头、冒号和空格以及第一个参数组成。如果给出了更多的参数,将发送续行,每个续行由一个选项卡和一个参数组成。

HTTPConnection.endheaders(message_body=None, *, encode_chunked=False)

向服务器发送一条空行,指示头的结尾。可选的 message_body 参数可用于传递与请求关联的消息正文。

如果 encode_chunkedTrue ,每次迭代的结果 message_body 将按中的指定进行块编码 RFC 7230 ,第3.3.1节。数据的编码方式取决于 message_body . 如果 message_body 实现 buffer interface 编码将导致单个块。如果 message_body 是一个 collections.abc.Iterable ,每次迭代 message_body 将生成一个块。如果 message_body 是一个 file object ,每次调用 .read() 将生成一个块。该方法在块编码数据结束后立即自动发出信号。 message_body .

注解

由于分块编码规范,由迭代器体生成的空块将被分块编码器忽略。这是为了避免目标服务器因编码错误而过早终止对请求的读取。

3.6 新版功能: 分块编码支持。这个 encode_chunked 已添加参数。

HTTPConnection.send(data)

将数据发送到服务器。只有在 endheaders() 方法已在 getresponse() 被称为。

httpResponse对象

HTTPResponse 实例封装来自服务器的HTTP响应。它提供对请求头和实体体的访问。响应是一个不可重复的对象,可以在WITH语句中使用。

在 3.5 版更改: 这个 io.BufferedIOBase 现在实现了接口,并且支持它的所有读卡器操作。

HTTPResponse.read([amt])

读取并返回响应正文,或直到下一个 amt 字节。

HTTPResponse.readinto(b)

将响应主体的下一个len(b)字节读取到缓冲区中 b . 返回读取的字节数。

3.3 新版功能.

HTTPResponse.getheader(name, default=None)

返回头的值 namedefault 如果没有标题匹配 name . 如果有多个标题具有名称 name ,返回由“,”联接的所有值。如果“default”不是单个字符串,而是任何一个iterable,则其元素也会以逗号连接返回。

HTTPResponse.getheaders()

返回(头、值)元组的列表。

HTTPResponse.fileno()

返回 fileno 基础套接字的。

HTTPResponse.msg

A http.client.HTTPMessage 包含响应头的实例。 http.client.HTTPMessage 是的子类 email.message.Message .

HTTPResponse.version

服务器使用的HTTP协议版本。HTTP/1.0为10,HTTP/1.1为11。

HTTPResponse.url

检索到的资源的URL,通常用于确定是否遵循了重定向。

HTTPResponse.headers

email.message.EmailMessage 实例。

HTTPResponse.status

服务器返回的状态代码。

HTTPResponse.reason

服务器返回的原因短语。

HTTPResponse.debuglevel

调试挂钩。如果 debuglevel 大于零,将在读取和分析响应时将消息打印到stdout。

HTTPResponse.closed

True 如果流已关闭。

HTTPResponse.geturl()

3.9 版后已移除: 反对赞成 url .

HTTPResponse.info()

3.9 版后已移除: 反对赞成 headers .

HTTPResponse.getstatus()

3.9 版后已移除: 反对赞成 status .

实例

下面是一个使用 GET 方法:

>>> import http.client
>>> conn = http.client.HTTPSConnection("www.python.org")
>>> conn.request("GET", "/")
>>> r1 = conn.getresponse()
>>> print(r1.status, r1.reason)
200 OK
>>> data1 = r1.read()  # This will return entire content.
>>> # The following example demonstrates reading data in chunks.
>>> conn.request("GET", "/")
>>> r1 = conn.getresponse()
>>> while chunk := r1.read(200):
...     print(repr(chunk))
b'<!doctype html>\n<!--[if"...
...
>>> # Example of an invalid request
>>> conn = http.client.HTTPSConnection("docs.python.org")
>>> conn.request("GET", "/parrot.spam")
>>> r2 = conn.getresponse()
>>> print(r2.status, r2.reason)
404 Not Found
>>> data2 = r2.read()
>>> conn.close()

下面是一个使用 HEAD 方法。请注意 HEAD 方法从不返回任何数据。::

>>> import http.client
>>> conn = http.client.HTTPSConnection("www.python.org")
>>> conn.request("HEAD", "/")
>>> res = conn.getresponse()
>>> print(res.status, res.reason)
200 OK
>>> data = res.read()
>>> print(len(data))
0
>>> data == b''
True

下面是一个演示如何 POST 请求::

>>> import http.client, urllib.parse
>>> params = urllib.parse.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'})
>>> headers = {"Content-type": "application/x-www-form-urlencoded",
...            "Accept": "text/plain"}
>>> conn = http.client.HTTPConnection("bugs.python.org")
>>> conn.request("POST", "", params, headers)
>>> response = conn.getresponse()
>>> print(response.status, response.reason)
302 Found
>>> data = response.read()
>>> data
b'Redirecting to <a href="http://bugs.python.org/issue12524">http://bugs.python.org/issue12524</a>'
>>> conn.close()

客户端 HTTP PUT 请求与 POST 请求。区别仅在于服务器端,HTTP服务器将允许通过 PUT 请求。应该注意的是,自定义HTTP方法也在 urllib.request.Request 通过设置适当的方法属性。下面是一个示例会话,演示如何发送 PUT 使用http.client:请求:

>>> # This creates an HTTP message
>>> # with the content of BODY as the enclosed representation
>>> # for the resource http://localhost:8080/file
...
>>> import http.client
>>> BODY = "***filecontents***"
>>> conn = http.client.HTTPConnection("localhost", 8080)
>>> conn.request("PUT", "/file", BODY)
>>> response = conn.getresponse()
>>> print(response.status, response.reason)
200, OK

httpmessage对象

http.client.HTTPMessage 实例保存来自HTTP响应的头。它是使用 email.message.Message 类。