python 标准库之 http
山雨欲来风满楼,最近不是很太平,希望世界和平吧。
python 标准库学习 之 http
http
是一个包,它收集了多个用于处理超文本传输协议的模块:
http.client
是一个低层级的 HTTP 协议客户端;对于高层级的 URL 访问请使用urllib.request
http.server
包含基于socketserver
的基本 HTTP 服务类http.cookies
包含一些有用来实现通过 cookies 进行状态管理的工具http.cookiejar
提供了 cookies 的持久化
本次只整理 http.client的内容,后面持续更新。
常量
class http.HTTPStatus
使用方法:
1 | from http import HTTPStatus |
HTTP状态码
状态码 | 映射名 | 详情 |
---|---|---|
100 |
CONTINUE |
HTTP/1.1 RFC 7231, 6.2.1 节 |
101 |
SWITCHING_PROTOCOLS |
HTTP/1.1 RFC 7231, 6.2.2 节 |
102 |
PROCESSING |
WebDAV RFC 2518, 10.1 节 |
200 |
OK |
HTTP/1.1 RFC 7231, 6.3.1 节 |
201 |
CREATED |
HTTP/1.1 RFC 7231, 6.3.2 节 |
202 |
ACCEPTED |
HTTP/1.1 RFC 7231, 6.3.3 节 |
203 |
NON_AUTHORITATIVE_INFORMATION |
HTTP/1.1 RFC 7231, 6.3.4 节 |
204 |
NO_CONTENT |
HTTP/1.1 RFC 7231, 6.3.5 节 |
205 |
RESET_CONTENT |
HTTP/1.1 RFC 7231, 6.3.6 节 |
206 |
PARTIAL_CONTENT |
HTTP/1.1 RFC 7233, 4.1 节 |
207 |
MULTI_STATUS |
WebDAV RFC 4918, 11.1 节 |
208 |
ALREADY_REPORTED |
WebDAV Binding Extensions RFC 5842, 7.1 节(实验性) |
226 |
IM_USED |
Delta Encoding in HTTP RFC 3229, 10.4.1 节 |
300 |
MULTIPLE_CHOICES :有多种资源可选择 |
HTTP/1.1 RFC 7231, 6.4.1 节 |
301 |
MOVED_PERMANENTLY :永久移动 |
HTTP/1.1 RFC 7231, 6.4.2 节 |
302 |
FOUND :临时移动 |
HTTP/1.1 RFC 7231, 6.4.3 节 |
303 |
SEE_OTHER :已经移动 |
HTTP/1.1 RFC 7231, 6.4.4 节 |
304 |
NOT_MODIFIED :没有修改 |
HTTP/1.1 RFC 7232, 4.1 节 |
305 |
USE_PROXY :使用代理 |
HTTP/1.1 RFC 7231, 6.4.5 节 |
307 |
TEMPORARY_REDIRECT :临时重定向 |
HTTP/1.1 RFC 7231, 6.4.7 节 |
308 |
PERMANENT_REDIRECT :永久重定向 |
Permanent Redirect RFC 7238, Section 3 (Experimental) |
400 |
BAD_REQUEST :错误请求 |
HTTP/1.1 RFC 7231, 6.5.1 节 |
401 |
UNAUTHORIZED :未授权 |
HTTP/1.1 Authentication RFC 7235, 3.1 节 |
402 |
PAYMENT_REQUIRED :保留,将来使用 |
HTTP/1.1 RFC 7231, 6.5.2 节 |
403 |
FORBIDDEN :禁止 |
HTTP/1.1 RFC 7231, 6.5.3 节 |
404 |
NOT_FOUND :没有找到 |
HTTP/1.1 RFC 7231, 6.5.4 节 |
405 |
METHOD_NOT_ALLOWED :该请求方法不允许 |
HTTP/1.1 RFC 7231, 6.5.5 节 |
406 |
NOT_ACCEPTABLE :不可接受 |
HTTP/1.1 RFC 7231, 6.5.6 节 |
407 |
PROXY_AUTHENTICATION_REQUIRED :要求使用代理验证身份 |
HTTP/1.1 Authentication RFC 7235, 3.1 节 |
408 |
REQUEST_TIMEOUT :请求超时 |
HTTP/1.1 RFC 7231, 6.5.7 节 |
409 |
CONFLICT :冲突 |
HTTP/1.1 RFC 7231, 6.5.8 节 |
410 |
GONE :已经不在了 |
HTTP/1.1 RFC 7231, 6.5.9 节 |
411 |
LENGTH_REQUIRED :长度要求 |
HTTP/1.1 RFC 7231, 6.5.10 节 |
412 |
PRECONDITION_FAILED :前提条件错误 |
HTTP/1.1 RFC 7232, 4.2 节 |
413 |
REQUEST_ENTITY_TOO_LARGE :请求体太大了 |
HTTP/1.1 RFC 7231, 6.5.11 节 |
414 |
REQUEST_URI_TOO_LONG :请求URI太长了 |
HTTP/1.1 RFC 7231, 6.5.12 节 |
415 |
UNSUPPORTED_MEDIA_TYPE :不支持的媒体格式 |
HTTP/1.1 RFC 7231, 6.5.13 节 |
416 |
REQUESTED_RANGE_NOT_SATISFIABLE |
HTTP/1.1 Range Requests RFC 7233, 4.4 节 |
417 |
EXPECTATION_FAILED :期望失败 |
HTTP/1.1 RFC 7231, 6.5.14 节 |
421 |
MISDIRECTED_REQUEST |
HTTP/2 RFC 7540, 9.1.2 节 |
422 |
UNPROCESSABLE_ENTITY :可加工实体 |
WebDAV RFC 4918, 11.2 节 |
423 |
LOCKED :锁着 |
WebDAV RFC 4918, 11.3 节 |
424 |
FAILED_DEPENDENCY :失败的依赖 |
WebDAV RFC 4918, 11.4 节 |
426 |
UPGRADE_REQUIRED :升级需要 |
HTTP/1.1 RFC 7231, 6.5.15 节 |
428 |
PRECONDITION_REQUIRED :先决条件要求 |
Additional HTTP Status Codes RFC 6585 |
429 |
TOO_MANY_REQUESTS :太多的请求 |
Additional HTTP Status Codes RFC 6585 |
431 |
REQUEST_HEADER_FIELDS_TOO_LARGE :请求头太大 |
Additional HTTP Status Codes RFC 6585 |
451 |
UNAVAILABLE_FOR_LEGAL_REASONS |
HTTP 状态码用于报告法律障碍 RFC 7725 |
500 |
INTERNAL_SERVER_ERROR :内部服务错误 |
HTTP/1.1 RFC 7231, 6.6.1 节 |
501 |
NOT_IMPLEMENTED :不可执行 |
HTTP/1.1 RFC 7231, 6.6.2 节 |
502 |
BAD_GATEWAY :无效网关 |
HTTP/1.1 RFC 7231, 6.6.3 节 |
503 |
SERVICE_UNAVAILABLE :服务不可用 |
HTTP/1.1 RFC 7231, 6.6.4 节 |
504 |
GATEWAY_TIMEOUT :网关超时 |
HTTP/1.1 RFC 7231, 6.6.5 节 |
505 |
HTTP_VERSION_NOT_SUPPORTED :HTTP版本不支持 |
HTTP/1.1 RFC 7231, 6.6.6 节 |
506 |
VARIANT_ALSO_NEGOTIATES :服务器存在内部配置错误 |
透明内容协商在: HTTP RFC 2295, 8.1 节(实验性) |
507 |
INSUFFICIENT_STORAGE :存储不足 |
WebDAV RFC 4918, 11.5 节 |
508 |
LOOP_DETECTED :循环检测 |
WebDAV Binding Extensions RFC 5842, 7.2 节(实验性) |
510 |
NOT_EXTENDED :不扩展 |
WebDAV Binding Extensions RFC 5842, 7.2 节(实验性) |
511 |
NETWORK_AUTHENTICATION_REQUIRED :要求网络身份验证 |
Additional HTTP Status Codes RFC 6585, 6 节 |
为了保持向后兼容性,枚举值也以常量形式出现在 http.client
模块中,。 枚举名等于常量名 (例如 http.HTTPStatus.OK
也可以是 http.client.OK
)。
http.client 对象
这个模块定义了实现 HTTP 和 HTTPS 协议客户端的类。 它通常不直接使用 — 模块 urllib.request
用它来处理使用 HTTP 和 HTTPS 的 URL。
参见 The Requests 是一个高级的实现http协议的http客户端接口库.
注意: HTTPS 支持仅在编译 Python 时启用了 SSL 支持的情况下(通过 ssl
模块)可用。
强烈建议看源代码 Lib/http/client.py
我摘取其中关于http请求状态的描述
1 |
|
类
class http.client.HTTPConnection(*host*, *port=None*, [*timeout*, ]*source_address=None*, *blocksize=8192*)
HTTPConnection
的实例代表与 HTTP 的一个连接事务。 它的实例化应当传入一个主机和可选的端口号。 如果没有传入端口号,如果主机字符串的形式为 主机:端口
则会从中提取端口,否则将使用默认的 HTTP 端口(80)。 如果给出了可选的 timeout 参数,则阻塞操作(例如连接尝试)将在指定的秒数之后超时(如果未给出,则使用全局默认超时设置)。 可选的 source_address 参数可以为一个 (主机, 端口) 元组,用作进行 HTTP 连接的源地址。 可选的 blocksize 参数可以字节为单位设置缓冲区的大小,用来发送文件类消息体。
举个例子,以下调用都是创建连接到同一主机和端口的服务器的实例:
1 | 'www.python.org') h1 = http.client.HTTPConnection( |
`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 各选项的ssl.SSLContext
实例。class http.client.`
HTTPResponse`(sock, debuglevel=0, method=None, url=None)
在成功连接后返回类的实例,而不是由用户直接实例化。
异常
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`ConnectionResetError
和BadStatusLine
的一个子类。 当尝试读取响应时的结果是未从连接读取到数据时由HTTPConnection.getresponse()
引发,表明远端已关闭连接。
常量
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
(未发现)。
HTTPConnection 对象
方法
HTTPConnection.request
(method, url, body=None, headers={}, , encode_chunked=False*)
这会使用 HTTP 请求方法 method 和选择器 url 向服务器发送请求。
如果给定 body,那么给定的数据会在信息头完成之后发送。它可能是一个 str
、一个 bytes-like object 、一个打开的 file object,或者 bytes
迭代器。如果 body 是字符串,它会按 HTTP 默认的 ISO-8859-1 编码;如果是一个字节类对象,它会按原样发送;如果是 file object ,文件的内容会被发送,这个文件对象应该支持 read()
方法。如果这个文件对象是一个 io.TextIOBase
实例, read()
方法返回的数据会按 ISO-8859-1 编码,否则 read()
方法返回的数据会按原样发送;如果 body 是一个迭代器,迭代器中的元素会被发送,直到迭代器耗尽。
headers 参数应是额外的随请求发送的 HTTP 信息头的字典。
如果 headers 既不包含 Content-Length 也没有 Transfer-Encoding,但存在请求正文,那么这些头字段中的一个会自动设定。如果 body 是 None
,那么对于要求正文的方法 (PUT
,POST
,和 PATCH
),Content-Length 头会被设为 0
。如果 body 是字符串或者类似字节的对象,并且也不是 文件,Content-Length 头会设为正文的长度。任何其他类型的 body (一般是文件或迭代器)会按块编码,这时会自动设定 Transfer-Encoding 头以代替 Content-Length。
在 headers 中指定 Transfer-Encoding 时, encode_chunked 是唯一相关的参数。如果 encode_chunked 为 False
,HTTPConnection 对象会假定所有的编码都由调用代码处理。如果为 True
,正文会按块编码。
HTTPConnection.`
set_debuglevel`(level)设置调试等级。 默认的调试等级为
0
,意味着不会打印调试输出。 任何大于0
的值将使得所有当前定义的调试输出被打印到 stdout。debuglevel
会被传给任何新创建的HTTPResponse
对象。HTTPConnection.`
set_tunnel`(host, port=None, headers=None)为 HTTP 连接隧道设置主机和端口。 这将允许通过代理服务器运行连接。
host 和 port 参数指明隧道连接的位置(即 CONNECT 请求所包含的地址,而 不是 代理服务器的地址)。
headers 参数应为一个随 CONNECT 请求发送的额外 HTTP 标头的映射。
例如,要通过一个运行于本机 8080 端口的 HTTPS 代理服务器隧道,我们应当向
HTTPSConnection
构造器传入代理的地址,并将我们最终想要访问的主机地址传给set_tunnel()
方法:1
2
3
4import http.client
"localhost", 8080) conn = http.client.HTTPSConnection(
"www.python.org") conn.set_tunnel(
"HEAD","/index.html") conn.request(HTTPConnection.connect()
当对象被创建后连接到指定的服务器。 默认情况下,如果客户端还未建立连接,此函数会在发送请求时自动被调用。
HTTPConnection.close()
关闭到服务器的连接。
HTTPConnection.blocksize
用于发送文件类消息体的缓冲区大小。
HTTPConnection.send(data)
发送数据到服务器 。这个方法直接使用将会在endheaders()方法后和
getresponse()
方法调用之前被调用
HTTPResponse 对象
HTTPResponse
对象实例绑定从服务器返回的 Http response 内容。 response是一个可迭代对象,可以使用with上下文语句来管理。
方法
HTTPResponse.read
([amt])读取并返回response body
HTTPResponse.`
readinto`(b)读取从 response body 的b长度的字节放到 buffer b中,并返回这个字节b。
HTTPResponse.getheader
(name, default=None)如果有匹配的header name,则返回 header name的值。如果不止一个header name的名字,则返回所有的值的字符串,通过逗号连接。
HTTPResponse.getheaders()
返回一个包含header和value的元组元素的列表
HTTPResponse.fileno()
Return the
fileno
of the underlying socket.返回底层套接字的fileno
HTTPResponse.msg
一个
http.client.HTTPMessage
消息的实例,包含response header。http.client.HTTPMessage
是email.message.Message
的子类HTTPResponse.version
Http response版本号,例如 HTTP/1.0, 11 for HTTP/1.1.
HTTPResponse.`
status`由服务器返回的状态码。
HTTPResponse.reason
从服务器返回的状态码
HTTPResponse.debuglevel
一个 debugging hook. 如果
debuglevel
大于0, 消息将会被打印到控制台。HTTPResponse.closed
如果stream关闭,返回true
实例:
一个使用get请求的实例
1 | import http.client |
一个使用head
方法的实例
1 | import http.client |
一个使用post
提交请求的实例
1 | import http.client, urllib.parse |
一个使用HTTP PUT
请求的实例
1 | # This creates an HTTP message |
HTTPMessage 对象
一个 http.client.HTTPMessage
的实例包含了http response 请求头. 是 email.message.Message
类的具体实现.
总结
通过阅读源码加深了对http协议的理解,看python实现的方式受益良多。继续加油!