http.clientHTTP协议客户端

源代码: Lib / http / client.py


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

另请参阅

对于更高级别的HTTP客户端界面,建议使用Requests包.

注意

仅当Python使用SSL支持编译时才能使用HTTP支持(通过ssl模块).

模块提供以下类:

class http.client.HTTPConnectionhost, port=None, [timeout, ] source_address=None, blocksize=8192

一个HTTPConnectioninstance表示一个HTTP服务器的事务。它应该被实例化,通过它传递一个主机和可选的端口号。如果没有传递端口号,如果它具有host:port,否则使用默认的HTTP端口(80)。如果可选timeout参数给出,阻塞操作(如连接尝试)将在很多秒后超时(如果没有给出,则使用全局默认超时设置)。可选source_address参数可以是(主机,端口)的元组,用作建立HTTP连接的源地址。可选blocksize参数设置缓冲区大小,以字节为单位,反映类似文件的消息体.

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

>>> 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:blocksize参数被添加了

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

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

请阅读安全考虑有关最佳实践的更多信息.

在版本3.2中更改:source_address, contextcheck_hostname被添加了

在版本3.2中更改:此类现在支持HTTPS虚拟主机(如果ssl.HAS_SNI为真).

在版本3.4中更改: strict参数已被删除。HTTP 0.9风格的“简单响应”不再受支持.

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

从版本3.6开始不推荐使用:key_filecert_file不赞成使用context。请改用ssl.SSLContext.load_cert_chain(),或者让ssl.create_default_context()选择系统的可信任CA证书给你

check_hostname参数也已弃用;应该使用ssl.SSLContext.check_hostnamecontext属性.

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

成功连接后返回的类别。用户没有直接实例.

更改版本3.4: strict参数已删除。HTTP 0.9样式“简单响应”不再受支持.

以下例外情况适用:

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。如果服务器使用我们不理解的HTTPstatus代码响应,则引发.

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状态码对于此模块中可用作常量的HTTP状态代码列表.

HTTPConnection对象

HTTPConnection实例具有以下方法:

HTTPConnection.requestmethod, url, body=None, headers={}, *, encode_chunked=False

这将使用HTTP requestmethod method和选择器url.

向服务器发送请求。如果指定了body,则在标头完成后发送指定的数据。它可能是str,一个字节对象,anopen 文件对象,或者bytes的可迭代。如果body是一个字符串,它编码为ISO-8859-1,HTTP的默认值。如果它是类似字节的对象,则按原样发送字节。如果是文件对象,发送文件的内容;这个文件对象应该至少支持read()方法。如果文件对象是io.TextIOBase的实例,则read()方法返回的数据将被编码为ISO-8859-1,否则read()返回的数据将被发送为是。如果body是一个可迭代的,那么theiterable的元素就会被发送,直到iterable耗尽为止.

headers参数应该是额外HTTP头的映射,以便与request

//如果headers既不包含Content-Length也不包含Transfer-Encoding,但是有一个请求体,其中一个头字段将自动添加。如果bodyNone,Content-Length标题设置为0用于期望正文的方法(PUT, POSTPATCH)。如果body是一个字符串或类似字节的对象,它也不是文件,则Content-Length标头设置为其长度。任何其他类型的body(一般的文件和迭代)将被块编码,并且将自动设置传输编码头而不是内容 – 长度

// encode_chunked只有在headers中指定了Transfer-Encoding时,参数才有意义。如果encode_chunkedFalse,则httpTPConnection对象假定所有编码都由调用代码处理。如果是 True,身体将被大块编码.

注意

已将分块传输编码添加到HTTP协议转换1.1中。除非已知HTTP服务器处理HTTP 1.1,否则调用者必须指定Content-Length,或者必须传递str或类似字节的对象,它也不是一个文件作为人体表示.

新版本3.2:body现在可以是一个可迭代的

更改版本3.6:如果在headers中没有设置Content-Length和Transfer-Encoding,则文件和可迭代的body对象现在都是块编码的.encode_chunked添加了参数。没有尝试确定fileobjects的内容长度

HTTPConnection.getresponse)

在发送请求以获取响应之后应该调用服务器。回收HTTPResponseinstance.

注意

注意你必须先阅读整个回复才能向服务器发送新请求.

更改版本3.5:如果ConnectionError或子类被提出,HTTPConnection当发送新请求时,对象将准备重新连接.

HTTPConnection.set_debuglevellevel

设置调试级别。默认调试级别是0,意味着打印nodebugging输出。任何大于0的值都会导致所有当前定义的调试输出打印到stdout。debuglevel传递给任何新的HTTPResponse创建的对象.

版本3.1.

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

设置HTTP Connect Tunneling的主机和端口。这允许通过代理服务器运行连接.

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

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

例如,要通过在port8080上本地运行的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)

这应该是与服务器建立连接后的第一次调用。它向服务器发送一行,包括method字符串,url字符串和HTTP版本(HTTP/1.1)。要禁用Host:Accept-Encoding:标题的自动发送(例如接受附加内容编码),请指定带有非假值的skip_hostskip_accept_encoding

HTTPConnection.putheaderheader, argument [, ]

发送 RFC 822 到服务器的样式标题。它向服务器发送一行代码,包括标题,冒号和空格以及第一个参数。如果给出了更多的参数,则会发送连续行,每行都包含一个制表符和一个参数.

HTTPConnection.endheadersmessage_body=None, *, encode_chunked=False

向服务器发送一个空行,表示标题的结尾。可选的message_body参数可用于传递与请求相关的信息.

如果encode_chunkedTruemessage_body的每次迭代的结果将按照 RFC 7230 ,3.3.1节中的规定进行块编码。数据的编码方式取决于message_body的类型。如果message_body执行缓冲区接口编码会产生一个块。如果message_bodycollections.abc.Iterablemessage_body的每次迭代都会产生一个块。如果message_body文件对象,每次调用.read()将导致一个块。该方法在message_body.

后立即自动发信号通知块编码数据的结尾

由于chunked编码规范,chunk-encoder将忽略由迭代器体提供的空块。这是为了避免由于编码格式错误而导致目标服务器提前终止请求的读取.

版本3.6中新增:分块编码支持。encode_chunked参数wasadded .

HTTPConnection.senddata

将数据发送到服务器。这应该只在endheaders()方法已被调用,之前getresponse()被称为

HTTPResponse对象

一个HTTPResponseinstance包装来自服务器的HTTP响应。它提供对请求标头和实体主体的访问。响应是一个可迭代的对象,可以在withstatement中使用.

更改版本3.5:现在实现了io.BufferedIOBase界面,支持所有的阅读器操作.

HTTPResponse.read ( [amt]

读取并返回响应体,或者直到下一个amt bytes.

HTTPResponse.readinto(b)

读到下一个len(b)字节响应体进入缓冲区b.Returns读取的字节数

3.3版本中的新功能

HTTPResponse.getheader// (name, default=None)

如果没有标题匹配,请返回标题namedefault的值name。如果有多个标题为name,返回’,’返回的所有值。如果’default’是除了单个字符串之外的任何可迭代,则其元素同样返回由逗号连接.

HTTPResponse.getheaders ( )

返回(标题,值)元组列表

HTTPResponse.fileno// ()

返回底层插座的fileno.

HTTPResponse.msg

一个http.client.HTTPMessage包含响应头的实例。http.client.HTTPMessageemail.message.Message.

HTTPResponse.version

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

HTTPResponse.status

服务器返回的状态码

HTTPResponse.reason

服务器返回的原因短语.

HTTPResponse.debuglevel

一个调试钩子。如果debuglevel大于零时,将在读取和解析响应时将消息打印到stdout .

HTTPResponse.closed

True如果溪流关闭了

例子

这是一个使用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 not r1.closed:...     print(r1.read(200))  # 200 bytesb"<!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()>>> datab"Redirecting to <a href="http://bugs.python.org/issue12524">http://bugs.python.org/issue12524</a>">>> conn.close()

客户端HTTP PUT请求与POST请求非常相似。差异只在于服务器端,HTTP服务器将允许通过PUT请求。应该注意的是,通过发送适当的+方法属性,也可以在urllib.request.Request中处理自定义HTTP方法+。这是一个示例会话,显示如何做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 class.