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-CookieSet-Cookie2标头中找到的各种命名参数(例如。domainexpires)通常被称为属性为了将它们与Python属性区分开来,本模块的文档使用术语cookie-attribute

模块定义了以下异常:

exception http.cookiejar.LoadError

FileCookieJar的实例在从文件加载Cookie失败时引发此异常。LoadErrorOSError的子类。

在版本3.3中已更改: LoadError已成为OSError的子类,而不是IOError

提供以下类:

class http.cookiejar.CookieJar(policy=None)

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.

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

policy是实现CookiePolicy接口的对象。有关其他参数,请参阅相应属性的文档。

CookieJar可以从磁盘上的文件加载Cookie,或者保存Cookie到文件。load()revert()方法被调用之前,从指定文件加载NOT此类的子类在FileCookieJar subclasses and co-operation with web browsers部分中进行了说明。

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)

构造函数参数只应作为关键字参数传递。blocked_domains是一系列域名,我们从不接受Cookie,也不会将Cookie传回。allowed_domains如果不是None,这是我们接受并返回Cookie的唯一域的序列。对于所有其他参数,请参阅CookiePolicyDefaultCookiePolicy对象的文档。

DefaultCookiePolicy实现Netscape和RFC 2965 Cookie的标准接受/拒绝规则。默认情况下,RFC 2109 cookie(即。在具有版本cookie属性为1的Set-Cookie头中接收的Cookie)根据RFC 2965规则进行处理。但是,如果RFC 2965处理被关闭或rfc2109_as_netscapeTrue,则RFC 2109 Cookie会被CookieJar实例降级为Netscape Cookie,通过将Cookie实例的version属性设置为0。DefaultCookiePolicy还提供一些参数,以允许对策略进行一些微调。

class http.cookiejar.Cookie

此类表示Netscape,RFC 2109和RFC 2965 cookie。不希望http.cookiejar的用户构造自己的Cookie实例。相反,如果需要,请在CookieJar实例中调用make_cookies()

也可以看看

模块urllib.request
使用自动Cookie处理的网址打开。
模块http.cookies
HTTP cookie类,主要用于服务器端代码。http.cookiejarhttp.cookies模块不依赖于彼此。
https://curl.haxx.se/rfc/cookie_spec.html T0>
原始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 T0>
RFC 2965的未完成勘误表。

RFC 2964 - 使用HTTP状态管理

21.24.1. CookieJar和FileCookieJar对象

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

CookieJar有以下方法:

Cookie标头添加到请求

如果政策允许(即。CookieJarCookiePolicy实例的rfc2965hide_cookie2属性分别为true和false), Cookie2标题也会在适当时添加。

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

在版本3.3: 请求对象需要origin_req_host属性中更改。依赖于已弃用的方法get_origin_req_host()已被移除。

CookieJar.extract_cookies(response, request)

从HTTP 响应中提取Cookie,并将其存储在策略允许的CookieJar中。

CookieJar将在响应参数中查找允许的Set-CookieSet-Cookie2 (根据CookiePolicy.set_ok()方法的批准)。

响应对象(通常调用urllib.request.urlopen()或类似的结果)应支持info()方法,它返回email.message.Message实例。

The request object (usually a urllib.request.Request instance) must support the methods get_full_url(), get_host(), unverifiable(), and origin_req_host attribute, as documented by urllib.request. 请求用于设置cookie属性的默认值以及检查是否允许设置cookie。

在版本3.3: 请求对象需要origin_req_host属性中更改。依赖于已弃用的方法get_origin_req_host()已被移除。

CookieJar.set_policy(policy)

设置要使用的CookiePolicy实例。

CookieJar.make_cookies(response, request)

响应对象提取的Cookie对象的返回序列。

有关响应请求参数所需的接口,请参阅extract_cookies()的文档。

如果政策声明可以这么做,请设置Cookie

设置Cookie,而不检查政策是否应该设置。

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

清除一些cookie。

如果没有参数调用,请清除所有Cookie。如果给定单个参数,则只会删除属于的Cookie。如果给定两个参数,将删除属于指定的和URL 路径的Cookie。如果给出三个参数,则会删除指定的路径名称的Cookie。

如果没有匹配的Cookie,则引发KeyError

CookieJar.clear_session_cookies()

舍弃所有会话Cookie。

丢弃所有包含具有真实discard属性的Cookie(通常是因为它们没有max-ageexpires cookie属性, discard cookie-attribute)。对于交互式浏览器,会话的结束通常对应于关闭浏览器窗口。

注意,除非你通过传递一个真实的ignore_discard参数,否则save()方法不会保存会话cookie。

FileCookieJar实现以下附加方法:

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

将Cookie保存到文件。

此基类引发NotImplementedError子类可以保留此方法未实现。

filename是要保存Cookie的文件的名称。如果未指定filename,则使用self.filename(其默认值为传递给构造函数的值(如果有));如果self.filenameNone,则会引发ValueError

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

如果为true,则从磁盘延迟加载Cookie。此属性不应分配给。这只是一个提示,因为这只会影响性能,而不是行为(除非磁盘上的cookie正在改变)。CookieJar对象可以忽略它。包含在标准库中的FileCookieJar类不会延迟加载Cookie。

21.24.2. FileCookieJar子类和与web浏览器的合作

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

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

可以使用Mozilla cookies.txt文件格式(也由Lynx和Netscape浏览器使用)加载并将Cookie保存到磁盘的FileCookieJar

注意

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

警告

如果您的Cookie具有丢失/损坏的不便,请在保存前备份您的Cookie,(有一些细微之处可能导致加载/保存往返程序中的文件略有更改)。

还要注意,Mozilla运行时保存的Cookie会被Mozilla破坏。

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

可以以与libwww-perl库的Set-Cookie3文件格式兼容的格式加载并将Cookie保存到磁盘的FileCookieJar如果要将cookie存储在人工可读的文件中,这很方便。

21.24.3. CookiePolicy对象

实现CookiePolicy接口的对象有以下方法:

CookiePolicy.set_ok(cookie, request)

返回布尔值,指示是否应从服务器接受cookie。

cookie t>是Cookie实例。请求是实现由CookieJar.extract_cookies()文档定义的接口的对象。

CookiePolicy.return_ok(cookie, request)

返回布尔值,指示是否应将cookie返回到服务器。

cookie t>是Cookie实例。请求是实现由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(),而不仅仅是请求域。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()中的文档相同。

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(这不太可能有用)。

21.24.4. DefaultCookiePolicy对象

实施接受和返回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实现以下附加方法:

DefaultCookiePolicy.blocked_domains()

返回被阻塞的域的序列(作为元组)。

DefaultCookiePolicy.set_blocked_domains(blocked_domains)

设置阻塞域的顺序。

DefaultCookiePolicy.is_blocked(domain)

返回是否位于设置或接收Cookie的黑名单上。

DefaultCookiePolicy.allowed_domains()

返回None或允许的域序列(作为元组)。

DefaultCookiePolicy.set_allowed_domains(allowed_domains)

设置允许的域的顺序,或None

DefaultCookiePolicy.is_not_allowed(domain)

返回是否不在白名单中,用于设置或接收Cookie。

DefaultCookiePolicy实例具有以下属性,它们都从同名的构造函数参数初始化,并且可以全部分配给它们。

DefaultCookiePolicy.rfc2109_as_netscape

如果为true,则请求CookieJar实例降级RFC 2109 Cookie(即。通过将Cookie实例的版本属性设置为0,在Netscape Cookie中接收到Cookie(Cookie版本为Set-Cookie默认值为None,在这种情况下,RFC 2109 cookie会降级,当且仅当RFC 2965处理被关闭。因此,RFC 2109 cookie默认降级。

一般严格开关:

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不会从未包含domain cookie属性的example.com返回Cookie)。

DefaultCookiePolicy.DomainRFC2965Match

设置Cookie时,需要完整的RFC 2965域匹配。

为方便起见,提供了以下属性,它们是上述标志的最有用的组合:

DefaultCookiePolicy.DomainLiberal

等于0(即。所有上述Netscape域严格标志关闭)。

DefaultCookiePolicy.DomainStrict

等效于DomainStrictNoDots|DomainStrictNonDomain

21.24.6. 实例¶ T0>

第一个示例显示了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/")