http.cookiejar --- HTTP 客户端的 Cookie 处理

源代码: Lib/http/cookiejar.py


The http.cookiejar module defines classes for automatic handling of HTTP cookies. It is useful for accessing websites that require small pieces of data -- cookies -- to be set on the client machine by an HTTP response from a web server, and then returned to the server in later HTTP requests.

Both the regular Netscape cookie protocol and the protocol defined by RFC 2965 are handled. RFC 2965 handling is switched off by default. RFC 2109 cookies are parsed as Netscape cookies and subsequently treated either as Netscape or RFC 2965 cookies according to the 'policy' in effect. Note that the great majority of cookies on the internet are Netscape cookies. http.cookiejar attempts to follow the de-facto Netscape cookie protocol (which differs substantially from that set out in the original Netscape specification), including taking note of the max-age and port cookie-attributes introduced with RFC 2965.

备注

The various named parameters found in Set-Cookie and Set-Cookie2 headers (for example, domain and expires) are conventionally referred to as attributes. To distinguish them from Python attributes, the documentation for this module uses the term cookie-attribute instead.

此模块定义了以下异常:

exception http.cookiejar.LoadError

FileCookieJar 实例在从文件加载 cookies 出错时抛出这个异常。 LoadErrorOSError 的一个子类。

在 3.3 版本发生变更: LoadError 曾经是 IOError 的子类型,现在它是 OSError 的一个别名。

提供了以下类:

class http.cookiejar.CookieJar(policy=None)

policy 是实现了 CookiePolicy 接口的一个对象。

CookieJar 类储存 HTTP cookies。它从 HTTP 请求提取 cookies,并在 HTTP 响应中返回它们。 CookieJar 实例在必要时自动处理包含 cookie 的到期情况。子类还负责储存和从文件或数据库中查找 cookies。

class http.cookiejar.FileCookieJar(filename=None, delayload=None, policy=None)

policy 是实现了 CookiePolicy 接口的一个对象。对于其他参数,参考相应属性的文档。

一个可以从硬盘中文件加载或保存 cookie 的 CookieJar。Cookies 会在 load()revert() 方法调用前从命名的文件中加载。子类的文档位于段落 FileCookieJar 的子类及其与 Web 浏览器的协同

此类不应被直接初始化 —— 请改用它的下列子类。

在 3.8 版本发生变更: 文件名形参支持 path-like object

class http.cookiejar.CookiePolicy

此类负责确定是否应从服务器接受每个 cookie 或将其返回给服务器。

class http.cookiejar.DefaultCookiePolicy(blocked_domains=None, allowed_domains=None, netscape=True, rfc2965=False, rfc2109_as_netscape=None, hide_cookie2=False, strict_domain=False, strict_rfc2965_unverifiable=True, strict_ns_unverifiable=False, strict_ns_domain=DefaultCookiePolicy.DomainLiberal, strict_ns_set_initial_dollar=False, strict_ns_set_path=False, secure_protocols=('https', 'wss'))

Constructor arguments should be passed as keyword arguments only. blocked_domains is a sequence of domain names that we never accept cookies from, nor return cookies to. allowed_domains if not None, this is a sequence of the only domains for which we accept and return cookies. secure_protocols is a sequence of protocols for which secure cookies can be added to. By default https and wss (secure websocket) are considered secure protocols. For all other arguments, see the documentation for CookiePolicy and DefaultCookiePolicy objects.

DefaultCookiePolicy implements the standard accept / reject rules for Netscape and RFC 2965 cookies. By default, RFC 2109 cookies (that is, cookies received in a Set-Cookie header with a version cookie-attribute of 1) are treated according to the RFC 2965 rules. However, if RFC 2965 handling is turned off or rfc2109_as_netscape is True, RFC 2109 cookies are 'downgraded' by the CookieJar instance to Netscape cookies, by setting the version attribute of the Cookie instance to 0. DefaultCookiePolicy also provides some parameters to allow some fine-tuning of policy.

class http.cookiejar.Cookie

This class represents Netscape, RFC 2109 and RFC 2965 cookies. It is not expected that users of http.cookiejar construct their own Cookie instances. Instead, if necessary, call make_cookies() on a CookieJar instance.

参见

模块 urllib.request

带有自动 cookie 处理的 URL 打开操作。

模块 http.cookies

HTTP cookie classes, principally useful for server-side code. The http.cookiejar and http.cookies modules do not depend on each other.

https://curl.se/rfc/cookie_spec.html

The specification of the original Netscape cookie protocol. Though this is still the dominant protocol, the 'Netscape cookie protocol' implemented by all the major browsers (and http.cookiejar) only bears a passing resemblance to the one sketched out in cookie_spec.html.

RFC 2109 - HTTP 状态管理机制

RFC 2965 所取代。使用 Set-Cookie version=1。

RFC 2965 - HTTP 状态管理机制

修正了错误的 Netscape 协议。使用 Set-Cookie2 来代替 Set-Cookie。没有广泛被使用。

https://kristol.org/cookie/errata.html

未完成的 RFC 2965 勘误表。

RFC 2964 - HTTP 状态管理的使用

CookieJar 和 FileCookieJar 对象

CookieJar 对象支持 iterator 协议,用于迭代包含的 Cookie 对象。

CookieJar 有以下方法:

request 中添加正确的 Cookie 头。

If policy allows (that is, the rfc2965 and hide_cookie2 attributes of the CookieJar's CookiePolicy instance are true and false respectively), the Cookie2 header is also added when appropriate.

The request object (usually a urllib.request.Request instance) must support the methods get_full_url(), has_header(), get_header(), header_items(), add_unredirected_header() and the attributes host, type, unverifiable and origin_req_host as documented by urllib.request.

在 3.3 版本发生变更: request object needs origin_req_host attribute. Dependency on a deprecated method get_origin_req_host() has been removed.

CookieJar.extract_cookies(response, request)

从 HTTP response 中提取 cookie,并在策略允许的情况下,将它们存储在 CookieJar 中。

CookieJar 将在 response 参数中寻找允许的 Set-CookieSet-Cookie2 头信息,并适当地存储 cookies(须经 CookiePolicy.set_ok() 方法批准)。

The response object (usually the result of a call to urllib.request.urlopen(), or similar) should support an info() method, which returns an email.message.Message instance.

The request object (usually a urllib.request.Request instance) must support the method get_full_url() and the attributes host, unverifiable and origin_req_host, as documented by urllib.request. The request is used to set default values for cookie-attributes as well as for checking that the cookie is allowed to be set.

在 3.3 版本发生变更: request object needs origin_req_host attribute. Dependency on a deprecated method get_origin_req_host() has been removed.

CookieJar.set_policy(policy)

设置要使用的 CookiePolicy 实例。

CookieJar.make_cookies(response, request)

返回从 response 对象中提取的 Cookie 对象的序列。

关于 responserequest 参数所需的接口,请参见 extract_cookies() 的文档。

如果策略规定可以这样做,就设置一个 Cookie

设置一个 Cookie,不检查策略来确认该 cookie 是否应当被设置。

CookieJar.clear([domain[, path[, name]]])

清除一些 cookie。

如果调用时没有参数,则清除所有的 cookie。如果给定一个参数,只有属于该 domain 的 cookies 将被删除。如果给定两个参数,那么属于指定的 domain 和 URL path 的 cookie 将被删除。 如果给定三个参数,那么属于指定的 domainpathname 的 cookie 将被删除

如果不存在匹配的 cookie,则会引发 KeyError

CookieJar.clear_session_cookies()

丢弃所有的会话 cookie。

Discards all contained cookies that have a true discard attribute (usually because they had either no max-age or expires cookie-attribute, or an explicit discard cookie-attribute). For interactive browsers, the end of a session usually corresponds to closing the browser window.

Note that the save() method won't save session cookies anyway, unless you ask otherwise by passing a true ignore_discard argument.

FileCookieJar 实现了下列附加方法:

FileCookieJar.save(filename=None, ignore_discard=False, ignore_expires=False)

将 cookie 保存到文件。

基类会引发 NotImplementedError。子类可以继续不实现该方法。

filename is the name of file in which to save cookies. If filename is not specified, self.filename is used (whose default is the value passed to the constructor, if any); if self.filename is None, ValueError is raised.

ignore_discard: 即使设定了丢弃 cookie 仍然保存它们。 ignore_expires: 即使 cookie 已超期仍然保存它们

文件如果已存在则会被覆盖,这将清除其所包含的全部 cookie。已保存的 cookie 可以使用 load()revert() 方法来恢复。

FileCookieJar.load(filename=None, ignore_discard=False, ignore_expires=False)

从文件加载 cookie。

旧的 cookie 将被保留,除非是被新加载的 cookie 所覆盖。

其参数与 save() 的相同。

指定的文件必须为该类所能理解的格式,否则将引发 LoadError。也可能会引发 OSError,例如当文件不存在的时候。

在 3.3 版本发生变更: 过去触发的 IOError,现在是 OSError 的别名。

FileCookieJar.revert(filename=None, ignore_discard=False, ignore_expires=False)

清除所有 cookie 并从保存的文件重新加载 cookie。

revert() 可以引发与 load() 相同的异常。如果执行失败,对象的状态将不会被改变。

FileCookieJar 实例具有下列公有属性:

FileCookieJar.filename

默认的保存 cookie 的文件的文件名。该属性可以被赋值。

FileCookieJar.delayload

如为真值,则惰性地从磁盘加载 cookie。该属性不应当被赋值。这只是一个提示,因为它只会影响性能,而不会影响行为(除非磁盘中的 cookie 被改变了)。 CookieJar 对象可能会忽略它。任何包括在标准库中的 FileCookieJar 类都不会惰性地加载 cookie。

FileCookieJar 的子类及其与 Web 浏览器的协同

提供了以下 CookieJar 子类用于读取和写入。

class http.cookiejar.MozillaCookieJar(filename=None, delayload=None, policy=None)

一个能够以 Mozilla cookies.txt 文件格式(该格式也被 curl 和 Lynx 以及 Netscape 浏览器所使用)从硬盘加载和存储 cookie 的 FileCookieJar

备注

这会丢失有关 RFC 2965 cookie 的信息,以及有关较新或非标准的 cookie 属性例如 port

警告

在存储之前备份你的 cookie,如果你的 cookie 丢失/损坏会造成麻烦的话(有一些微妙的因素可能导致文件在加载/保存的往返过程中发生细微的变化)。

还要注意在 Mozilla 运行期间保存的 cookie 将可能被 Mozilla 清除。

class http.cookiejar.LWPCookieJar(filename=None, delayload=None, policy=None)

一个能够以 libwww-perl 库的 Set-Cookie3 文件格式从磁盘加载和存储 cookie 的 FileCookieJar。这适用于当你想以人类可读的文件来保存 cookie 的情况。

在 3.8 版本发生变更: 文件名形参支持 path-like object

CookiePolicy objects

实现了 CookiePolicy 接口的对象具有下列方法:

CookiePolicy.set_ok(cookie, request)

返回指明是否应当从服务器接受 cookie 的布尔值。

cookie 是一个 Cookie 实例。 request 是一个实现了由 CookieJar.extract_cookies() 的文档所定义的接口的对象。

CookiePolicy.return_ok(cookie, request)

返回指明是否应当将 cookie 返回给服务器的布尔值。

cookie 是一个 Cookie 实例。 request 是一个实现了 CookieJar.add_cookie_header() 的文档所定义的接口的对象。

CookiePolicy.domain_return_ok(domain, request)

对于给定的 cookie 域如果不应当返回 cookie 则返回 False

此方法是一种优化操作。它消除了检查每个具有特定域的 cookie 的必要性(这可能会涉及读取许多文件)。从 domain_return_ok()path_return_ok() 返回真值并将所有工作留给 return_ok().

如果 domain_return_ok() 为 cookie 域返回真值,则会为 cookie 路径调用 path_return_ok()。在其他情况下,则不会为该 cookie 域调用 path_return_ok()return_ok()。如果 path_return_ok() 返回真值,则会调用 return_ok() 并附带 Cookie 对象本身以进行全面检查。在其他情况下,都永远不会为该 cookie 路径调用 return_ok()

请注意 domain_return_ok() 会针对每个 cookie 域被调用,而非只针对 request 域。 例如,该函数会针对 ".example.com""www.example.com" 被调用,如果 request 域为 "www.example.com" 的话。 对于 path_return_ok() 也是如此。

request 参数与 return_ok() 的文档所说明的一致。

CookiePolicy.path_return_ok(path, request)

对于给定的 cookie 路径如果不应当返回 cookie 则返回 False

请参阅 domain_return_ok() 的文档。

除了实现上述方法,CookiePolicy 接口的实现还必须提供下列属性,指明应当使用哪种协议以及如何使用。 所有这些属性都可以被赋值。

CookiePolicy.netscape

实现 Netscape 协议。

CookiePolicy.rfc2965

实现 RFC 2965 协议。

CookiePolicy.hide_cookie2

不要向请求添加 Cookie2 标头(此标头是提示服务器请求方能识别 RFC 2965 cookie)。

定义 CookiePolicy 类的最适用方式是通过子类化 DefaultCookiePolicy 并重写部分或全部上述的方法。 CookiePolicy 本身可被用作 '空策略' 以允许设置和接收所有的 cookie(但这没有什么用处)。

DefaultCookiePolicy objects

实现接收和返回 cookie 的标准规则。

RFC 2965 和 Netscape cookie 均被涵盖。RFC 2965 处理默认关闭。

提供自定义策略的最容易方式是重写此类并在你重写的实现中添加你自己的额外检查之前调用其方法:

import http.cookiejar
class MyCookiePolicy(http.cookiejar.DefaultCookiePolicy):
    def set_ok(self, cookie, request):
        if not http.cookiejar.DefaultCookiePolicy.set_ok(self, cookie, request):
            return False
        if i_dont_want_to_store_this_cookie(cookie):
            return False
        return True

在实现 CookiePolicy 接口所要求的特性之外,该类还允许你阻止和允许特定的域设置和接收 cookie。 还有一些严格性开关允许你将相当宽松的 Netscape 协议规则收紧一点(代价是可能会阻止某些无害的 cookie)。

A domain blocklist and allowlist is provided (both off by default). Only domains not in the blocklist and present in the allowlist (if the allowlist is active) participate in cookie setting and returning. Use the blocked_domains constructor argument, and blocked_domains() and set_blocked_domains() methods (and the corresponding argument and methods for allowed_domains). If you set an allowlist, you can turn it off again by setting it to None.

阻止名单或允许名单中不以点号开头的域必须与要匹配的 cookie 域完全相等。 例如,"example.com" 将匹配阻止名单条目 "example.com",但 "www.example.com" 则不匹配。 以点号开头的域也将与更明确的域相匹配。 例如,"www.example.com""www.coyote.example.com" 都将匹配 ".example.com" (但 "example.com" 本身则不匹配)。 IP 地址则例外。 举例来说,如果 blocked_domains 包含 "192.168.1.2"".168.1.2",则 192.168.1.2 会被阻止,但 193.168.1.2 不会被阻止。

DefaultCookiePolicy 实现了下列附加方法:

DefaultCookiePolicy.blocked_domains()

返回被阻止域的序列(元组类型)。

DefaultCookiePolicy.set_blocked_domains(blocked_domains)

设置被阻止域的序列。

DefaultCookiePolicy.is_blocked(domain)

如果 domain 在设置或接受 cookie 的阻止列表中则返回 True

DefaultCookiePolicy.allowed_domains()

Return None, or the sequence of allowed domains (as a tuple).

DefaultCookiePolicy.set_allowed_domains(allowed_domains)

Set the sequence of allowed domains, or None.

DefaultCookiePolicy.is_not_allowed(domain)

如果 domain 不在设置或接受 cookie 的允许列表中则返回 True

DefaultCookiePolicy 实例具有下列属性,它们都是基于同名的构造器参数来初始化的,并且都可以被赋值。

DefaultCookiePolicy.rfc2109_as_netscape

If true, request that the CookieJar instance downgrade RFC 2109 cookies (that is, cookies received in a Set-Cookie header with a version cookie-attribute of 1) to Netscape cookies by setting the version attribute of the Cookie instance to 0. The default value is None, in which case RFC 2109 cookies are downgraded if and only if RFC 2965 handling is turned off. Therefore, RFC 2109 cookies are downgraded by default.

通用严格性开关:

DefaultCookiePolicy.strict_domain

不允许网站设置带国家码顶级域的包含两部分的域名例如 .co.uk, .gov.uk, .co.nz 等。 此开关尚未十分完善,并不保证有效!

RFC 2965 协议严格性开关:

DefaultCookiePolicy.strict_rfc2965_unverifiable

遵循针对不可验证事务的 RFC 2965 规则(不可验证事务通常是由重定向或请求发布在其它网站的图片导致的)。如果该属性为假值,则 永远不会 基于可验证性而阻止 cookie。

Netscape 协议严格性开关:

DefaultCookiePolicy.strict_ns_unverifiable

即便是对 Netscape cookie 也要应用 RFC 2965 规则。

DefaultCookiePolicy.strict_ns_domain

指明针对 Netscape cookie 的域匹配规则的严格程度。可接受的值见下文。

DefaultCookiePolicy.strict_ns_set_initial_dollar

忽略 Set-Cookie: 标头中名称以 '$' 开头的 cookie。

DefaultCookiePolicy.strict_ns_set_path

不允许设置路径与请求 URL 路径不匹配的 cookie。

strict_ns_domain 是一组旗标。 其值是通过或运算来构造的(例如,DomainStrictNoDots|DomainStrictNonDomain 表示同时设置两个旗标)。

DefaultCookiePolicy.DomainStrictNoDots

When setting cookies, the 'host prefix' must not contain a dot (for example, www.foo.bar.com can't set a cookie for .bar.com, because www.foo contains a dot).

DefaultCookiePolicy.DomainStrictNonDomain

Cookies that did not explicitly specify a domain cookie-attribute can only be returned to a domain equal to the domain that set the cookie (for example, spam.example.com won't be returned cookies from example.com that had no domain cookie-attribute).

DefaultCookiePolicy.DomainRFC2965Match

当设置 cookie 时,要求完整的 RFC 2965 域匹配。

下列属性是为方便使用而提供的,是上述旗标的几种最常用组合:

DefaultCookiePolicy.DomainLiberal

Equivalent to 0 (that is, all of the above Netscape domain strictness flags switched off).

DefaultCookiePolicy.DomainStrict

等价于 DomainStrictNoDots|DomainStrictNonDomain

例子

第一个例子显示了 http.cookiejar 的最常见用法:

import http.cookiejar, urllib.request
cj = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")

这个例子演示了如何使用你的 Netscape, Mozilla 或 Lynx cookie 打开一个 URL (假定 cookie 文件位置采用 Unix/Netscape 惯例):

import os, http.cookiejar, urllib.request
cj = http.cookiejar.MozillaCookieJar()
cj.load(os.path.join(os.path.expanduser("~"), ".netscape", "cookies.txt"))
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")

下一个例子演示了 DefaultCookiePolicy 的使用。启用 RFC 2965 cookie,在设置和返回 Netscape cookie 时更严格地限制域,以及阻止某些域设置 cookie 或返回它们:

import urllib.request
from http.cookiejar import CookieJar, DefaultCookiePolicy
policy = DefaultCookiePolicy(
    rfc2965=True, strict_ns_domain=Policy.DomainStrict,
    blocked_domains=["ads.net", ".ads.net"])
cj = CookieJar(policy)
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")