20.21. cookielib — HTTP 客户端的 Cookie 处理 — Python 文档
目录
20.21. 曲奇库 — HTTP 客户端的 Cookie 处理
2.4 版中的新功能。
源代码: :source:`Lib/cookielib.py`
cookielib 模块定义了自动处理 HTTP cookie 的类。 这对于访问需要小块数据(cookies)的网站非常有用,这些数据通过来自 Web 服务器的 HTTP 响应在客户端计算机上设置,然后在以后的 HTTP 请求中返回到服务器。
常规的 Netscape cookie 协议和由 RFC 2965 定义的协议都被处理。 RFC 2965 处理默认关闭。 RFC 2109 cookie 被解析为 Netscape cookie,随后根据有效的“策略”被视为 Netscape 或 RFC 2965 cookie。 请注意,Internet 上的绝大多数 cookie 都是 Netscape cookie。 cookielib 试图遵循事实上的 Netscape cookie 协议(与原始 Netscape 规范中规定的有很大不同),包括注意 max-age
和 port
RFC 2965 中引入的 cookie 属性。
笔记
Set-Cookie 和 Set-Cookie2 标头中的各种命名参数(例如 domain
和 expires
) 通常被称为 属性 。 为了将它们与 Python 属性区分开来,该模块的文档使用术语 cookie-attribute 代替。
该模块定义了以下异常:
- exception cookielib.LoadError
FileCookieJar 的实例在无法从文件加载 cookie 时引发此异常。
笔记
为了向后兼容 Python 2.4(引发
IOError
),LoadError 是IOError
的子类。
提供以下类:
- class cookielib.CookieJar(policy=None)
policy 是一个实现 CookiePolicy 接口的对象。
CookieJar 类存储 HTTP cookie。 它从 HTTP 请求中提取 cookie,并在 HTTP 响应中返回它们。 CookieJar 实例在必要时自动使包含的 cookie 过期。 子类还负责从文件或数据库中存储和检索 cookie。
- class cookielib.FileCookieJar(filename, delayload=None, policy=None)
policy 是一个实现 CookiePolicy 接口的对象。 对于其他参数,请参阅相应属性的文档。
一个 CookieJar,它可以从磁盘上的文件加载 cookie,也可以将 cookie 保存到磁盘文件。 在调用 load() 或 revert() 方法之前,Cookie 是 NOT 从命名文件加载的。 此类的子类记录在 FileCookieJar 子类和与 Web 浏览器的合作 部分。
- class cookielib.CookiePolicy
- 此类负责决定是否应从服务器接受/返回每个 cookie。
- class cookielib.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)
构造函数参数应仅作为关键字参数传递。 blocked_domains 是一个域名序列,我们从不接受来自的 cookie,也不向其返回 cookie。 allowed_domains 如果不是 None,这是我们接受和返回 cookie 的唯一域的序列。 对于所有其他参数,请参阅 CookiePolicy 和 DefaultCookiePolicy 对象的文档。
DefaultCookiePolicy 实现了 Netscape 和 RFC 2965 cookie 的标准接受/拒绝规则。 默认情况下,RFC 2109 cookie(即 根据 RFC 2965 规则处理在 Set-Cookie 标头中收到的版本 cookie-attribute 为 1) 的 cookie。 但是,如果 RFC 2965 处理被关闭或 rfc2109_as_netscape 是
True
,RFC 2109 cookie 会被 CookieJar 实例“降级”为 Netscape cookie,方法是将 Cookie 实例的 X195X] 属性设置为 0。 DefaultCookiePolicy 还提供了一些参数以允许对策略进行一些微调。
- class cookielib.Cookie
- 此类代表 Netscape、RFC 2109 和 RFC 2965 cookie。 预计 cookielib 的用户不会构建自己的 Cookie 实例。 相反,如有必要,请在 CookieJar 实例上调用
make_cookies()
。
也可以看看
- 模块 urllib2
- 使用自动 cookie 处理打开 URL。
- 模块 Cookie
- HTTP cookie 类,主要用于服务器端代码。 cookielib 和 Cookie 模块不相互依赖。
- https://curl.haxx.se/rfc/cookie_spec.html
- 原始 Netscape cookie 协议的规范。 尽管这仍然是主要协议,但所有主要浏览器(和 cookielib)实现的“Netscape cookie 协议”与
cookie_spec.html
中勾画的协议只有一点相似之处。 - RFC 2109 - HTTP 状态管理机制
- 已被 RFC 2965 废弃。 使用 Set-Cookie 版本=1。
- RFC 2965 - HTTP 状态管理机制
- 修复了错误的 Netscape 协议。 使用 Set-Cookie2 代替 Set-Cookie。 使用不广泛。
- http://kristol.org/cookie/errata.html
- 未完成的 RFC 2965 勘误表。
RFC 2964 - 使用 HTTP 状态管理
20.21.1。 CookieJar 和 FileCookieJar 对象
CookieJar 对象支持 [X39X]iterator 协议,用于迭代包含的 Cookie 对象。
CookieJar 有以下方法:
- CookieJar.add_cookie_header(request)
将正确的 Cookie 标头添加到 request。
如果政策允许(即。 CookieJar 的 CookiePolicy 实例的
rfc2965
和hide_cookie2
属性分别为真和假),Cookie2 标头适当的时候也会加入。request 对象(通常是 urllib2.Request 实例)必须支持方法
get_full_url()
、get_host()
、get_type()
、unverifiable()
、get_origin_req_host()
、has_header()
、get_header()
、header_items()
和add_unredirected_header()
,如 [X220X2323] 所记载]。
- CookieJar.extract_cookies(response, request)
从 HTTP response 中提取 cookie 并将它们存储在策略允许的 CookieJar 中。
CookieJar 将在 response 参数中查找允许的 Set-Cookie 和 Set-Cookie2 标头,并适当地存储 cookie(主题到 CookiePolicy.set_ok() 方法的批准)。
response 对象(通常是调用 urllib2.urlopen() 或类似的结果)应该支持
info()
方法,该方法返回一个带有 [ X169X] 方法(通常是 mimetools.Message 实例)。request 对象(通常是 urllib2.Request 实例)必须支持方法
get_full_url()
、get_host()
、unverifiable()
和 [ X136X],如 urllib2 所记载。 该请求用于设置 cookie 属性的默认值以及检查是否允许设置 cookie。
- CookieJar.set_policy(policy)
- 设置要使用的 CookiePolicy 实例。
- CookieJar.make_cookies(response, request)
从 response 对象中提取的 Cookie 对象的返回序列。
有关 response 和 request 参数所需的接口,请参阅 extract_cookies() 的文档。
- CookieJar.set_cookie_if_ok(cookie, request)
- 如果政策说可以这样做,则设置 Cookie。
- CookieJar.set_cookie(cookie)
- 设置 Cookie,无需检查策略以查看是否应设置。
- CookieJar.clear([domain[, path[, name]]])
清除一些cookie。
如果不带参数调用,则清除所有 cookie。 如果给出单个参数,则只会删除属于该 域 的 cookie。 如果给定两个参数,则删除属于指定 domain 和 URL path 的 cookie。 如果给定三个参数,则删除具有指定 domain、path 和 name 的 cookie。
如果不存在匹配的 cookie,则引发
KeyError
。
- CookieJar.clear_session_cookies()
丢弃所有会话 cookie。
丢弃所有包含的具有真正
discard
属性的 cookie(通常是因为它们没有max-age
或expires
cookie 属性,或明确的discard
cookie-属性)。 对于交互式浏览器,会话的结束通常对应于关闭浏览器窗口。请注意,
save()
方法无论如何都不会保存会话 cookie,除非您通过传递真正的 ignore_discard 参数来另外询问。
FileCookieJar 实现了以下附加方法:
- FileCookieJar.save(filename=None, ignore_discard=False, ignore_expires=False)
将 cookie 保存到文件中。
这个基类引发
NotImplementedError
。 子类可能会保留此方法未实现。filename 是保存 cookie 的文件名。 如果未指定 filename,则使用
self.filename
(其默认值是传递给构造函数的值,如果有); 如果self.filename
是 None,则ValueError
被提升。ignore_discard:保存设置为丢弃的偶数cookie。 ignore_expires:保存已过期的 cookie
如果文件已经存在,则会被覆盖,从而擦除它包含的所有 cookie。 稍后可以使用 load() 或 revert() 方法恢复保存的 cookie。
- FileCookieJar.load(filename=None, ignore_discard=False, ignore_expires=False)
从文件加载 cookie。
除非被新加载的 cookie 覆盖,否则会保留旧 cookie。
参数与 save() 相同。
命名文件必须采用类可以理解的格式,否则将引发 LoadError。 此外,可能会引发
IOError
,例如,如果文件不存在。笔记
为了向后兼容 Python 2.4(引发
IOError
),LoadError 是IOError
的子类。
- FileCookieJar.revert(filename=None, ignore_discard=False, ignore_expires=False)
清除所有 cookie 并从保存的文件中重新加载 cookie。
FileCookieJar 实例具有以下公共属性:
- FileCookieJar.filename
- 保存 cookie 的默认文件的文件名。 可以分配此属性。
- FileCookieJar.delayload
- 如果为 true,则从磁盘延迟加载 cookie。 不应分配此属性。 这只是一个提示,因为这只会影响性能,不会影响行为(除非磁盘上的 cookie 发生变化)。 CookieJar 对象可能会忽略它。 标准库中包含的 FileCookieJar 类都不会延迟加载 cookie。
20.21.2. FileCookieJar 子类以及与 Web 浏览器的合作
以下 CookieJar 子类用于读写。
- class cookielib.MozillaCookieJar(filename, delayload=None, policy=None)
一个 FileCookieJar,可以以 Mozilla
cookies.txt
文件格式(Lynx 和 Netscape 浏览器也使用这种格式)加载和保存 cookie 到磁盘。笔记
Firefox Web 浏览器的第 3 版不再以
cookies.txt
文件格式写入 cookie。笔记
这会丢失有关 RFC 2965 cookie 以及更新或非标准 cookie 属性(例如
port
)的信息。警告
如果您的 cookie 丢失/损坏会带来不便,请在保存之前备份您的 cookie(有一些细微之处可能会导致文件在加载/保存往返过程中发生轻微变化)。
另请注意,Mozilla 运行时保存的 cookie 将被 Mozilla 破坏。
- class cookielib.LWPCookieJar(filename, delayload=None, policy=None)
- FileCookieJar 可以从与 libwww-perl 库的
Set-Cookie3
文件格式兼容的格式加载和保存 cookie 到磁盘。 如果您想将 cookie 存储在人类可读的文件中,这会很方便。
20.21.3. CookiePolicy 对象
实现 CookiePolicy 接口的对象有以下方法:
- CookiePolicy.set_ok(cookie, request)
返回布尔值,指示是否应从服务器接受 cookie。
cookie 是一个 cookielib.Cookie 实例。 request 是实现 CookieJar.extract_cookies() 文档定义的接口的对象。
- CookiePolicy.return_ok(cookie, request)
返回布尔值,指示是否应将 cookie 返回给服务器。
cookie 是一个 cookielib.Cookie 实例。 request 是实现 CookieJar.add_cookie_header() 文档定义的接口的对象。
- CookiePolicy.domain_return_ok(domain, request)
如果不应该返回 cookie,则返回 false,给定 cookie 域。
这种方法是一种优化。 它不需要检查具有特定域的每个 cookie(这可能涉及读取许多文件)。 从 domain_return_ok() 和 path_return_ok() 返回 true 将所有工作留给 return_ok()。
如果 domain_return_ok() 为 cookie 域返回 true,则为 cookie 路径调用 path_return_ok()。 否则,永远不会为该 cookie 域调用 path_return_ok() 和 return_ok()。 如果 path_return_ok() 返回 true,则使用 Cookie 对象本身调用 return_ok() 以进行全面检查。 否则,永远不会为该 cookie 路径调用 return_ok()。
请注意,每个 cookie 域都会调用 domain_return_ok(),而不仅仅是 request 域。 例如,如果请求域为
"www.example.com"
,则该函数可能会同时使用".example.com"
和"www.example.com"
调用。 path_return_ok() 也是如此。request 参数与 return_ok() 的文档相同。
- CookiePolicy.path_return_ok(path, request)
如果不应该返回 cookie,则返回 false,给定 cookie 路径。
请参阅 domain_return_ok() 的文档。
除了实现上述方法之外,CookiePolicy 接口的实现还必须提供以下属性,指示应该使用哪些协议以及如何使用。 所有这些属性都可以分配给。
- CookiePolicy.netscape
- 实现 Netscape 协议。
- CookiePolicy.rfc2965
- 实施 RFC 2965 协议。
- CookiePolicy.hide_cookie2
- 不要向请求添加 Cookie2 标头(此标头的存在向服务器表明我们了解 RFC 2965 cookie)。
定义 CookiePolicy 类的最有用的方法是从 DefaultCookiePolicy 子类化并覆盖上述部分或全部方法。 CookiePolicy 本身可以用作“空策略”以允许设置和接收任何和所有 cookie(这不太可能有用)。
20.21.4. DefaultCookiePolicy 对象
实现接受和返回 cookie 的标准规则。
RFC 2965 和 Netscape cookie 都包含在内。 RFC 2965 处理默认关闭。
提供您自己的策略的最简单方法是在添加您自己的附加检查之前覆盖此类并在您覆盖的实现中调用其方法:
import cookielib
class MyCookiePolicy(cookielib.DefaultCookiePolicy):
def set_ok(self, cookie, request):
if not cookielib.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 为代价)。
提供域黑名单和白名单(默认情况下均关闭)。 只有不在黑名单中但出现在白名单中的域(如果白名单处于活动状态)参与 cookie 设置和返回。 使用 blocked_domains 构造函数参数以及 blocked_domains()
和 set_blocked_domains()
方法(以及 allowed_domains 的相应参数和方法)。 如果您设置了白名单,您可以通过将其设置为 无 再次将其关闭。
阻止或允许列表中不以点开头的域必须等于要匹配的 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 的黑名单中。
- DefaultCookiePolicy.allowed_domains()
- 返回 None,或允许域的序列(作为元组)。
- DefaultCookiePolicy.set_allowed_domains(allowed_domains)
- 设置允许域的顺序,或 None。
- DefaultCookiePolicy.is_not_allowed(domain)
- 返回 domain 是否不在设置或接收 cookie 的白名单中。
DefaultCookiePolicy 实例具有以下属性,它们都从同名的构造函数参数初始化,并且可以全部分配给。
- DefaultCookiePolicy.rfc2109_as_netscape
如果为 true,则请求 CookieJar 实例降级 RFC 2109 cookie(即 通过将 Cookie 实例的版本属性设置为 0,将在 Set-Cookie 标头中收到的具有 1) 版本 cookie 属性的 cookie 发送到 Netscape cookie。 默认值为 None,在这种情况下,当且仅当 RFC 2965 处理关闭时,RFC 2109 cookie 才会降级。 因此,RFC 2109 cookie 默认被降级。
2.5 版中的新功能。
一般严格开关:
- DefaultCookiePolicy.strict_domain
- 不允许网站使用国家代码顶级域(如
.co.uk
、.gov.uk
、.co.nz
.etc)设置两部分域。 这远非完美,不能保证工作!
RFC 2965 协议严格性开关:
- DefaultCookiePolicy.strict_rfc2965_unverifiable
- 遵循关于不可验证交易的 RFC 2965 规则(通常,不可验证交易是由重定向或请求托管在另一个站点上的图像引起的)。 如果这是错误的,cookies 从不根据可验证性被阻止
Netscape 协议严格性开关:
- DefaultCookiePolicy.strict_ns_unverifiable
- 将 RFC 2965 规则应用于无法验证的交易,甚至适用于 Netscape cookie。
- DefaultCookiePolicy.strict_ns_domain
- 指示 Netscape cookie 的域匹配规则的严格程度的标志。 有关可接受的值,请参见下文。
- DefaultCookiePolicy.strict_ns_set_initial_dollar
- 忽略 Set-Cookie 中的 cookie:名称以
'$'
开头的标题。
- DefaultCookiePolicy.strict_ns_set_path
- 不允许设置路径与请求 URI 路径不匹配的 cookie。
strict_ns_domain
是标志的集合。 它的值是由或一起构造的(例如,DomainStrictNoDots|DomainStrictNonDomain
表示两个标志都被设置)。
- DefaultCookiePolicy.DomainStrictNoDots
- 设置 cookie 时,“主机前缀”不得包含点(例如。
www.foo.bar.com
无法为.bar.com
设置 cookie,因为www.foo
包含一个点)。
- DefaultCookiePolicy.DomainStrictNonDomain
- 未明确指定
domain
cookie 属性的 cookie 只能返回到与设置 cookie 的域相同的域(例如spam.example.com
不会从example.com
返回没有domain
cookie 属性的 cookie)。
- DefaultCookiePolicy.DomainRFC2965Match
- 设置 cookie 时,需要完整的 RFC 2965 域匹配。
为方便起见,提供了以下属性,并且是上述标志的最有用的组合:
- DefaultCookiePolicy.DomainLiberal
- 相当于 0(即。 所有上述 Netscape 域严格标志都已关闭)。
- DefaultCookiePolicy.DomainStrict
- 相当于
DomainStrictNoDots|DomainStrictNonDomain
。
20.21.5。 Cookie 对象
Cookie 实例的 Python 属性大致对应于各种 cookie 标准中指定的标准 cookie 属性。 对应关系不是一一对应的,因为分配默认值有复杂的规则,因为 max-age
和 expires
cookie 属性包含等效信息,并且因为 RFC 2109 cookie 可能是 '由 cookielib 从版本 1 降级到版本 0 (Netscape) cookie。
除了在 CookiePolicy 方法中的极少数情况外,不需要为这些属性赋值。 该类不强制执行内部一致性,因此如果您这样做,您应该知道自己在做什么。
- Cookie.version
- 整数或 无 。 Netscape cookie 具有 版本 0。 RFC 2965 和 RFC 2109 cookie 的
version
cookie 属性为 1。 但是,请注意 cookielib 可能会将 RFC 2109 cookie“降级”为 Netscape cookie,在这种情况下 version 为 0。
- Cookie.name
- Cookie 名称(字符串)。
- Cookie.value
- Cookie 值(字符串),或 None。
- Cookie.port
- 表示一个端口或一组端口的字符串(例如。 '80' 或 '80,8080'),或 无 。
- Cookie.path
- Cookie 路径(一个字符串,例如
'/acme/rocket_launchers'
)。
- Cookie.secure
True
如果 cookie 只应通过安全连接返回。
- Cookie.expires
- 自纪元以来的以秒为单位的整数到期日期,或 无 。 另请参阅 is_expired() 方法。
- Cookie.discard
True
如果这是会话 cookie。
- Cookie.comment
- 来自服务器的字符串注释,用于解释此 cookie 的功能,或 None。
- Cookie.comment_url
- 链接到来自服务器的解释此 cookie 功能的评论的 URL,或 无 。
- Cookie.rfc2109
True
如果此 cookie 是作为 RFC 2109 cookie 接收的(即 cookie 到达 Set-Cookie 标头,并且该标头中版本 cookie-attribute 的值为 1)。 提供此属性是因为 cookielib 可能会将 RFC 2109 cookie '降级'为 Netscape cookie,在这种情况下 version 为 0。2.5 版中的新功能。
- Cookie.port_specified
True
如果服务器明确指定了一个端口或一组端口(在 Set-Cookie / Set-Cookie2 标头中)。
- Cookie.domain_specified
True
如果服务器明确指定了域。
- Cookie.domain_initial_dot
True
如果服务器明确指定的域以点开头 ('.'
)。
Cookie 可能具有额外的非标准 cookie 属性。 这些可以使用以下方法访问:
- Cookie.has_nonstandard_attr(name)
- 如果 cookie 具有命名的 cookie-attribute,则返回 true。
- Cookie.get_nonstandard_attr(name, default=None)
- 如果 cookie 具有命名的 cookie-attribute,则返回其值。 否则,返回 default。
- Cookie.set_nonstandard_attr(name, value)
- 设置命名 cookie-attribute 的值。
Cookie 类还定义了以下方法:
- Cookie.is_expired([now=None])
True
如果 cookie 已经过了服务器请求它应该过期的时间。 如果给出 now(自纪元以来的秒数),则返回 cookie 是否在指定时间过期。
20.21.6. 例子
第一个例子展示了 cookielib 最常见的用法:
import cookielib, urllib2
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")
此示例说明如何使用 Netscape、Mozilla 或 Lynx cookie 打开 URL(假设 Unix/Netscape 约定用于 cookie 文件的位置):
import os, cookielib, urllib2
cj = cookielib.MozillaCookieJar()
cj.load(os.path.join(os.path.expanduser("~"), ".netscape", "cookies.txt"))
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")
下一个示例说明了 DefaultCookiePolicy 的使用。 打开 RFC 2965 cookie,在设置和返回 Netscape cookie 时对域更严格,并阻止某些域设置 cookie 或让它们返回:
import urllib2
from cookielib import CookieJar, DefaultCookiePolicy
policy = DefaultCookiePolicy(
rfc2965=True, strict_ns_domain=DefaultCookiePolicy.DomainStrict,
blocked_domains=["ads.net", ".ads.net"])
cj = CookieJar(policy)
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")