21.24. http.cookiejar
- HTTP客户端的Cookie处理¶
源代码: Lib / http / cookiejar.py
http.cookiejar
模块定义了用于自动处理HTTP Cookie的类。它对于访问需要小块数据(cookie)的网站非常有用,可通过来自Web服务器的HTTP响应在客户端计算机上设置,然后在以后的HTTP请求中返回到服务器。
将处理常规Netscape cookie协议和由 RFC 2965定义的协议。默认情况下,RFC 2965处理被关闭。 RFC 2109 Cookie将被解析为Netscape Cookie,随后根据“策略”生效,被视为Netscape或RFC 2965 Cookie。请注意,互联网上的绝大多数Cookie都是Netscape Cookie。http.cookiejar
尝试遵循事实上的Netscape Cookie协议(与原始Netscape规范中的协议大不相同),包括注意max-age
和使用RFC 2965引入的port
cookie属性。
注意
在Set-Cookie和Set-Cookie2标头中找到的各种命名参数(例如。domain
和expires
)通常被称为属性。为了将它们与Python属性区分开来,本模块的文档使用术语cookie-attribute。
模块定义了以下异常:
FileCookieJar
的实例在从文件加载Cookie失败时引发此异常。LoadError
是OSError
的子类。
提供以下类:
policy是实现
CookiePolicy
接口的对象。CookieJar
类存储HTTP Cookie。它从HTTP请求中提取Cookie,并在HTTP响应中返回。CookieJar
实例会在必要时自动过期包含的Cookie。The CookieJar class stores HTTP cookies. It extracts cookies from HTTP requests, and returns them in HTTP responses. CookieJar instances automatically expire contained cookies when necessary. Subclasses are also responsible for storing and retrieving cookies from a file or database.
policy是实现
CookiePolicy
接口的对象。有关其他参数,请参阅相应属性的文档。CookieJar
可以从磁盘上的文件加载Cookie,或者保存Cookie到文件。在load()
或revert()
方法被调用之前,从指定文件加载NOT此类的子类在FileCookieJar subclasses and co-operation with web browsers部分中进行了说明。
这个类负责决定每个cookie是否应该被接受/返回到服务器。
构造函数参数只应作为关键字参数传递。blocked_domains是一系列域名,我们从不接受Cookie,也不会将Cookie传回。allowed_domains如果不是
None
,这是我们接受并返回Cookie的唯一域的序列。对于所有其他参数,请参阅CookiePolicy
和DefaultCookiePolicy
对象的文档。DefaultCookiePolicy
实现Netscape和RFC 2965 Cookie的标准接受/拒绝规则。默认情况下,RFC 2109 cookie(即。在具有版本cookie属性为1的Set-Cookie头中接收的Cookie)根据RFC 2965规则进行处理。但是,如果RFC 2965处理被关闭或rfc2109_as_netscape
是True
,则RFC 2109 Cookie会被CookieJar
实例降级为Netscape Cookie,通过将Cookie
实例的version
属性设置为0。DefaultCookiePolicy
还提供一些参数,以允许对策略进行一些微调。
此类表示Netscape,RFC 2109和RFC 2965 cookie。不希望
http.cookiejar
的用户构造自己的Cookie
实例。相反,如果需要,请在CookieJar
实例中调用make_cookies()
。
也可以看看
- 模块
urllib.request
- 使用自动Cookie处理的网址打开。
- 模块
http.cookies
- HTTP cookie类,主要用于服务器端代码。
http.cookiejar
和http.cookies
模块不依赖于彼此。 - https://curl.haxx.se/rfc/cookie_spec.html
- 原始Netscape Cookie协议的规范。尽管这仍然是主要的协议,但是所有主要浏览器(和
http.cookiejar
)实现的“Netscape cookie协议”只是与在cookie_spec.html
。 - RFC 2109 - HTTP状态管理机制
- 由RFC 2965已过时。使用版本= 1的Set-Cookie。
- RFC 2965 - HTTP状态管理机制
- Netscape协议修复了错误。使用Set-Cookie2代替Set-Cookie。不广泛使用。
- http://kristol.org/cookie/errata.html
- RFC 2965的未完成勘误表。
RFC 2964 - 使用HTTP状态管理
21.24.1. CookieJar and FileCookieJar Objects¶
CookieJar
对象支持iterator协议,用于对包含的Cookie
对象进行迭代。
CookieJar
有以下方法:
将Cookie标头添加到请求。
如果政策允许(即。the
rfc2965
andhide_cookie2
attributes of theCookieJar
‘sCookiePolicy
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 methodsget_full_url()
,get_host()
,get_type()
,unverifiable()
,has_header()
,get_header()
,header_items()
,add_unredirected_header()
andorigin_req_host
attribute as documented byurllib.request
.在版本3.3: 请求对象需要
origin_req_host
属性中更改。依赖于已弃用的方法get_origin_req_host()
已被移除。
从HTTP 响应中提取Cookie,并将其存储在策略允许的
CookieJar
中。CookieJar
将在响应参数中查找允许的Set-Cookie和Set-Cookie2 (根据CookiePolicy.set_ok()
方法的批准)。响应对象(通常调用
urllib.request.urlopen()
或类似的结果)应支持info()
方法,它返回email.message.Message
实例。The request object (usually a
urllib.request.Request
instance) must support the methodsget_full_url()
,get_host()
,unverifiable()
, andorigin_req_host
attribute, as documented byurllib.request
. 请求用于设置cookie属性的默认值以及检查是否允许设置cookie。在版本3.3: 请求对象需要
origin_req_host
属性中更改。依赖于已弃用的方法get_origin_req_host()
已被移除。
设置要使用的
CookiePolicy
实例。
从响应对象提取的
Cookie
对象的返回序列。有关响应和请求参数所需的接口,请参阅
extract_cookies()
的文档。
如果政策声明可以这么做,请设置
Cookie
。
设置
Cookie
,而不检查政策是否应该设置。
清除一些cookie。
如果没有参数调用,请清除所有Cookie。如果给定单个参数,则只会删除属于域的Cookie。如果给定两个参数,将删除属于指定的域和URL 路径的Cookie。如果给出三个参数,则会删除指定的域,路径和名称的Cookie。
如果没有匹配的Cookie,则引发
KeyError
。
舍弃所有会话Cookie。
丢弃所有包含具有真实
discard
属性的Cookie(通常是因为它们没有max-age
或expires
cookie属性,discard
cookie-attribute)。对于交互式浏览器,会话的结束通常对应于关闭浏览器窗口。注意,除非你通过传递一个真实的ignore_discard参数,否则
save()
方法不会保存会话cookie。
FileCookieJar
实现以下附加方法:
将Cookie保存到文件。
此基类引发
NotImplementedError
。子类可以保留此方法未实现。filename是要保存Cookie的文件的名称。如果未指定filename,则使用
self.filename
(其默认值为传递给构造函数的值(如果有));如果self.filename
是None
,则会引发ValueError
。ignore_discard:保存即将设置为丢弃的Cookie。ignore_expires:保存已过期的Cookie
如果文件已经存在,则会被覆盖,从而擦除其包含的所有Cookie。保存的Cookie可以稍后使用
load()
或revert()
方法恢复。
从文件加载Cookie。
保留旧cookie,除非被新加载的cookie覆盖。
参数与
save()
相同。命名文件必须采用该类可以理解的格式,否则将引发
LoadError
。此外,可能会引发OSError
,例如,如果文件不存在。
FileCookieJar
实例具有以下公共属性:
保存Cookie的默认文件的文件名。此属性可以分配给。
如果为true,则从磁盘延迟加载Cookie。此属性不应分配给。这只是一个提示,因为这只会影响性能,而不是行为(除非磁盘上的cookie正在改变)。
CookieJar
对象可以忽略它。包含在标准库中的FileCookieJar
类不会延迟加载Cookie。
21.24.2. FileCookieJar subclasses and co-operation with web browsers¶
提供以下CookieJar
子类用于读取和写入。
可以使用Mozilla
cookies.txt
文件格式(也由Lynx和Netscape浏览器使用)加载并将Cookie保存到磁盘的FileCookieJar
。注意
这会丢失有关RFC 2965 cookie以及有关较新或非标准cookie属性(如
port
)的信息。警告
如果您的Cookie具有丢失/损坏的不便,请在保存前备份您的Cookie,(有一些细微之处可能导致加载/保存往返程序中的文件略有更改)。
还要注意,Mozilla运行时保存的Cookie会被Mozilla破坏。
可以以与libwww-perl库的
Set-Cookie3
文件格式兼容的格式加载并将Cookie保存到磁盘的FileCookieJar
如果要将cookie存储在人工可读的文件中,这很方便。
21.24.3. CookiePolicy Objects¶
实现CookiePolicy
接口的对象有以下方法:
返回布尔值,指示是否应从服务器接受cookie。
cookie t>是
Cookie
实例。请求是实现由CookieJar.extract_cookies()
文档定义的接口的对象。
返回布尔值,指示是否应将cookie返回到服务器。
cookie t>是
Cookie
实例。请求是实现由CookieJar.add_cookie_header()
文档定义的接口的对象。
给定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()
,而不仅仅是请求域。For example, the function might be called with both".example.com"
and"www.example.com"
if the request domain is"www.example.com"
. 对于path_return_ok()
也是如此。请求参数与
return_ok()
中的文档相同。
如果cookie不应该返回,返回false,给定cookie路径。
请参阅
domain_return_ok()
的文档。
除了实现上述方法之外,CookiePolicy
接口的实现还必须提供以下属性,指示应使用哪些协议以及如何使用。所有这些属性可以分配给。
实现Netscape协议。
实现RFC 2965协议。
不要向请求添加Cookie2头(此头的存在表示服务器,我们了解RFC 2965 cookie)。
定义CookiePolicy
类的最有用的方法是通过从DefaultCookiePolicy
子类化并覆盖上述部分或全部方法。CookiePolicy
本身可以用作“空策略”,允许设置和接收任何和所有Cookie(这不太可能有用)。
21.24.4. 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)。
提供域黑名单和白名单(默认都关闭)。只有不在黑名单中且位于白名单中(如果白名单处于活动状态)的域才会参与Cookie设置并返回。使用blocked_domains构造函数参数和blocked_domains()
和set_blocked_domains()
方法(以及allowed_domains )。如果您设置了白名单,可以将其设置为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
实现以下附加方法:
返回被阻塞的域的序列(作为元组)。
设置阻塞域的顺序。
返回域是否位于设置或接收Cookie的黑名单上。
返回
None
或允许的域序列(作为元组)。
设置允许的域的顺序,或
None
。
返回域是否不在白名单中,用于设置或接收Cookie。
DefaultCookiePolicy
实例具有以下属性,它们都从同名的构造函数参数初始化,并且可以全部分配给它们。
如果为true,则请求
CookieJar
实例降级RFC 2109 Cookie(即。通过将Cookie
实例的版本属性设置为0,在Netscape Cookie中接收到Cookie(Cookie版本为Set-Cookie默认值为None
,在这种情况下,RFC 2109 cookie会降级,当且仅当RFC 2965处理被关闭。因此,RFC 2109 cookie默认降级。
一般严格开关:
不允许网站设置具有国家/地区代码顶级域(如
.co.uk
,.gov.uk
,.co.nz
.etc。这是远非完美,不能保证工作!
RFC 2965协议严格开关:
遵循关于不可验证事务的RFC 2965规则(通常,不可验证的事务是由重定向或对托管在另一个站点上的图像的请求引起的)。如果这是假的,基于可验证性,cookies 从不被阻止
Netscape协议严格开关:
对不可验证的事务应用RFC 2965规则,甚至对Netscape cookie。
标记指示Netscape Cookie的域匹配规则的严格程度。请参阅下面的可接受值。
忽略Set-Cookie中的Cookie:名称以
'$'
开头的标题。
不允许设置其路径不与路径匹配请求URI的Cookie。
strict_ns_domain
是一个容器的标志。它的值由一起构造(例如,DomainStrictNoDots|DomainStrictNonDomain
意味着两个标志都被设置)。
设置Cookie时,“主机前缀”不能包含点(例如。
www.foo.bar.com
无法为.bar.com
设置Cookie,因为www.foo
包含一个点。
未明确指定
domain
cookie属性的Cookie只能返回到与设置Cookie的域相等的域(例如。spam.example.com
不会从未包含domain
cookie属性的example.com
返回Cookie)。
设置Cookie时,需要完整的RFC 2965域匹配。
为方便起见,提供了以下属性,它们是上述标志的最有用的组合:
等于0(即。所有上述Netscape域严格标志关闭)。
等效于
DomainStrictNoDots|DomainStrictNonDomain
。
21.24.5. Cookie Objects¶
Cookie
实例具有大致对应于各种Cookie标准中指定的标准Cookie属性的Python属性。由于max-age
和expires
cookie属性包含等效信息,因为对应关系不是一对一的,因为分配默认值有复杂的规则,因为RFC 2109 Cookie可能会被http.cookiejar
从版本1降级到版本0(Netscape)Cookie。
除非在CookiePolicy
方法中的罕见情况,否则不必分配这些属性。该类不强制内部一致性,所以你应该知道你在做什么,如果你这样做。
整数或
None
。Netscape Cookie有version
0。RFC 2965和RFC 2109 Cookie的version
cookie属性为1。但请注意,http.cookiejar
可能会将RFC 2109 Cookie降级为Netscape Cookie,在这种情况下version
为0。
Cookie名称(字符串)。
Cookie值(字符串),或
None
。
表示端口或一组端口的字符串(例如,'80'或'80,8080')或
None
。
Cookie路径(字符串,例如。
'/acme/rocket_launchers'
)。
True
如果Cookie只应通过安全连接返回。
从纪元开始的整数到期日期(以秒为单位),或
None
。另请参见is_expired()
方法。
True
如果这是会话Cookie。
来自服务器的字符串注释解释此Cookie的功能,或
None
。
URL链接到来自服务器的解释此Cookie功能的注释,或
None
。
True
如果此Cookie是作为RFC 2109 Cookie接收的(即。Cookie到达Set-Cookie头,并且该头中的版本cookie属性的值为1)。提供此属性是因为http.cookiejar
可能会将RFC 2109 Cookie降级为Netscape Cookie,在这种情况下version
为0。
True
如果服务器(在Set-Cookie / Set-Cookie2头中)明确指定了一个端口或一组端口。
True
如果服务器显式指定了域。
True
如果服务器显式指定的域以点('.'
)开头。
Cookie可能具有其他非标准Cookie属性。这些可以使用以下方法访问:
如果cookie具有命名的cookie属性,则返回其值。否则,返回默认值。
设置命名的cookie属性的值。
Cookie
类还定义了以下方法:
True
如果Cookie已经过了服务器请求的时间,则应该到期。如果给定现在(自纪元以来的秒数),则返回Cookie是否在指定时间到期。
21.24.6. Examples¶
第一个示例显示了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/")