21.12。 http.client
- HTTP协议客户端¶
本模块定义了HTTP和HTTPS协议的客户端实现。通常来说,该模块不能直接使用,需要模块urllib.request
调用该模块来处理使用HTTP和HTTPS的URL。
参考
推荐使用Requests package包处理高级别HTTP客户端接口。
注意
仅当Python通过SSL支持(通过ssl
模块)进行编译时,HTTPS支持才可用。
本模块提供以下类:
- class
http.client.
HTTPConnection
(host, port=None, [timeout, ]source_address=None)¶ 一个
HTTPConnection
实例表示与HTTP服务器端的一次事务。通过传参host地址和端口号进行实例化。没有端口号传参,也可以通过host传参,形式同host:port
,都没有的话,默认端口号为80。如果可选参数 timeout给出传参,阻塞操作(如连接)将在给出的秒数后超时(如果未给出该参数,默认使用全局默认超时设置值)。可选参数source_address可以是一个元组,形式同 (host, port),作为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中已更改:已删除严格参数。不再支持HTTP 0.9样式的“简单响应”。
- class
http.client.
HTTPSConnection
(host, port=None, key_file=None, cert_file=None, [timeout, ]source_address=None, *, context=None, check_hostname=None)¶ 该类是
HTTPConnection
的子类,使用SSL,用于与服务器端的安全通信。默认端口是443
。如果需要指定上下文context,必须使用ssl.SSLContext
实例化,它用于描述不同的SSL选项。key_file和cert_file已被弃用,请改用
ssl.SSLContext.load_cert_chain()
或让ssl.create_default_context()
为您选择系统的受信任的CA证书。check_hostname参数也已弃用;应使用上下文的ssl.SSLContext.check_hostname
属性。有关最佳做法的详情,请参阅Security considerations。
在版本3.2中更改: 源地址,上下文和check_hostname已添加。
在版本3.2中更改:此类现在支持HTTPS虚拟主机(如果可能的话)(即,如果
ssl.HAS_SNI
为true)。在版本3.4中已更改:已删除严格参数。不再支持HTTP 0.9样式的“简单响应”。
在版本3.4.3中更改:此类现在默认执行所有必需的证书和主机名检查。要还原到上一个未验证的行为,
ssl._create_unverified_context()
可以传递到上下文参数。
- class
http.client.
HTTPResponse
(sock, debuglevel=0, method=None, url=None)¶ 该类是在连接成功后返回的实例。不需要用户直接实例化。
在版本3.4中已更改:已删除严格参数。不再支持HTTP 0.9样式“简单响应”。
可能会涉及到的异常类,见下:
- 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
¶ 是
ConnectionResetError
类和BadStatusLine
类的子类。由方法HTTPConnection.getresponse()
引起,当试图读取连接的响应结果时,读取不到数据,意味着远端已关闭了连接。版本3.5中的新功能:以前,
BadStatusLine
('')
本模块中定义的常量包括:
-
http.client.
HTTP_PORT
¶ HTTP协议的默认端口值(总为
80
)。
-
http.client.
HTTPS_PORT
¶ HTTPS协议的默认端口值(总为
443
)。
-
http.client.
responses
¶ 该字典类匹配HTTP1.1状态码在W3C中的命名。
Example:
http.client.responses[http.client.NOT_FOUND]
就是'Not Found'
.
本模块中HTTP状态码的常量值列表可参考HTTP status codes。
21.12.1. HTTPConnection Objects¶
HTTPConnection
实例拥有方法如下:
-
HTTPConnection.
request
(method, url, body=None, headers={})¶ 该方法会向服务器端发送一个请求,入参为HTTP请求方法method和选择器url。
如果指定了入参body ,那么在 headers发送完成后就发送body的数据。它可能是一个字符串、 一个 类似字节对象、 打开的 文件对象,或可迭代的 类似字节对象 。如果 body 是一个字符串,它按 ISO-8859-1进行编码,默认 HTTP 。如果body是一个类似字节对象,按字节发送。如果body是一个 文件对象,发送的是文件的内容;这个文件对象至少可支持
read()
方法。If the file object has amode
attribute, the data returned by theread()
method will be encoded as ISO-8859-1 unless themode
attribute contains the substringb
, otherwise the data returned byread()
is sent as is. 如果body是可迭代的,则可迭代的元素按照原样发送,直到可迭代被耗尽。参数 headers 应该是附带的HTTP报文头的映射,与请求一起发送。
如果参数 headers 不包括内容长度项,那么就自动添加一个。If body is
None
, the Content-Length header is set to0
for methods that expect a body (PUT
,POST
, andPATCH
). 如果body是字符串或字节对象,则将Content-Length头设置为其长度。If body is a file object and it works to callfstat()
on the result of itsfileno()
method, then the Content-Length header is set to thest_size
reported by thefstat
call. 否则不添加Content-Length头。版本3.2中的新功能: 正文现在可以是可迭代的。
-
HTTPConnection.
getresponse
()¶ 应该在发送请求后调用以从服务器获取响应。返回
HTTPResponse
实例。注意
请注意,您必须先阅读完整的响应,然后才能向服务器发送新的请求。
在版本3.5中已更改:如果发生
ConnectionError
或子类,则在发送新请求时,HTTPConnection
对象将准备重新连接。
-
HTTPConnection.
set_debuglevel
(level)¶ 设置调试级别。默认调试级别为
0
,表示不打印调试输出。任何大于0
的值都将导致所有当前定义的调试输出被打印到stdout。debuglevel
会传递到创建的任何新HTTPResponse
对象。版本3.1中的新功能。
-
HTTPConnection.
set_tunnel
(host, port=None, headers=None)¶ 设置HTTP Connect隧道的主机和端口。这允许通过代理服务器运行连接。
主机和端口参数指定隧道连接的端点(即,CONNECT请求中包含的地址,不是代理服务器的地址)。
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
()¶ 关闭与服务器的连接。
作为使用上述request()
方法的替代方法,您还可以使用以下四个函数逐步发送请求。
-
HTTPConnection.
putrequest
(request, selector, skip_host=False, skip_accept_encoding=False)¶ 这应该是在连接到服务器之后的第一个调用。它向由请求字符串,选择器字符串和HTTP版本(
HTTP/1.1
)组成的服务器发送一行。To disable automatic sending ofHost:
orAccept-Encoding:
headers (for example to accept additional content encodings), specify skip_host or skip_accept_encoding with non-False values.
-
HTTPConnection.
putheader
(header, argument[, ...])¶ 向服务器发送 RFC 822类型头文件。它发送一行到服务器,包括头,冒号和空格,以及第一个参数。如果给出更多的参数,则发送连续行,每行由一个制表符和一个参数组成。
-
HTTPConnection.
endheaders
(message_body=None)¶ 发送空白行到服务器,用信号通知头的结束。可选的message_body参数可用于传递与请求相关联的消息体。如果消息头是字符串,消息体将与消息头在相同的分组中发送,否则它将在单独的分组中发送。
-
HTTPConnection.
send
(data)¶ 将数据发送到服务器。只有在调用
endheaders()
方法和调用getresponse()
之前,才应该直接使用此方法。
21.12.2. HTTPResponse Objects¶
HTTPResponse
实例包装来自服务器的HTTP响应。它提供对请求标头和实体主体的访问。响应是一个可迭代的对象,可以在with语句中使用。
在3.5版中已更改:现在实现了io.BufferedIOBase
界面,并支持其所有阅读器操作。
-
HTTPResponse.
read
([amt])¶ 读取并返回响应正文或直到下一个amt字节。
-
HTTPResponse.
readinto
(b)¶ 读取响应主体的下一个len(b)字节到缓冲区b中。返回读取的字节数。
版本3.3中的新功能。
-
HTTPResponse.
getheader
(name, default=None)¶ 如果没有与名称匹配的标头,请返回标头name或默认的值。如果有多个头名称name,则返回由','连接的所有值。如果'default'是除了单个字符串之外的任何可迭代,它的元素类似地返回用逗号连接。
-
HTTPResponse.
getheaders
()¶ 返回(标题,值)元组的列表。
-
HTTPResponse.
fileno
()¶ 返回底层套接字的
fileno
。
-
HTTPResponse.
msg
¶ 包含响应标头的
http.client.HTTPMessage
实例。http.client.HTTPMessage
是email.message.Message
的子类。
-
HTTPResponse.
version
¶ 服务器使用的HTTP协议版本。10用于HTTP / 1.0,11用于HTTP / 1.1。
-
HTTPResponse.
status
¶ 服务器返回的状态代码。
-
HTTPResponse.
reason
¶ 服务器返回的原因短语。
-
HTTPResponse.
debuglevel
¶ 调试挂钩。如果
debuglevel
大于零,则会在读取和解析响应时将消息打印到stdout。
-
HTTPResponse.
closed
¶ 如果流已关闭,则为
True
。
21.12.3. 示例¶
使用 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 bytes
b'<!doctype html>\n<!--[if"...
...
>>> # Example of an invalid request
>>> 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
>>> # 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
21.12.4. HTTPMessage Objects¶
http.client.HTTPMessage
实例保存来自HTTP响应的标头。它使用email.message.Message
类实现。