http.cookiejar
— HTTP 客戶端的 Cookie 處理¶
http.cookiejar
模組定義了用於自動處理 HTTP Cookie 的類。它對於訪問需要由 Web 伺服器的 HTTP 響應在客戶端機器上設定少量資料(cookies)的網站非常有用,然後在以後的 HTTP 請求中將其返回給伺服器。
常規的 Netscape Cookie 協議和 RFC 2965 定義的協議均已處理。RFC 2965 處理預設是關閉的。RFC 2109 Cookie 被解析為 Netscape Cookie,然後根據生效的“策略”被視為 Netscape 或 RFC 2965 Cookie。請注意,網際網路上絕大多數 Cookie 都是 Netscape Cookie。http.cookiejar
嘗試遵循事實上的 Netscape Cookie 協議(該協議與原始 Netscape 規範中規定的協議大相徑庭),包括注意 RFC 2965 中引入的 max-age
和 port
Cookie 屬性。
註解
在 Set-Cookie 和 Set-Cookie2 標頭中找到的各種命名引數(例如 domain
和 expires
)通常稱為屬性。為了將它們與 Python 屬性區分開來,此模組的文件使用了術語Cookie 屬性。
該模組定義了以下異常
- exception http.cookiejar.LoadError¶
FileCookieJar
的例項在無法從檔案載入 Cookie 時引發此異常。LoadError
是OSError
的子類。
提供了以下類
- class http.cookiejar.CookieJar(policy=None)¶
policy 是一個實現
CookiePolicy
介面的物件。CookieJar
類儲存 HTTP Cookie。它從 HTTP 請求中提取 Cookie,並在 HTTP 響應中返回它們。CookieJar
例項會在必要時自動使包含的 Cookie 過期。子類還負責從檔案或資料庫中儲存和檢索 Cookie。
- class http.cookiejar.FileCookieJar(filename=None, delayload=None, policy=None)¶
policy 是一個實現
CookiePolicy
介面的物件。有關其他引數,請參閱相應屬性的文件。CookieJar
可以從磁碟上的檔案載入 Cookie,也可能將 Cookie 儲存到檔案中。在呼叫load()
或revert()
方法之前,不會從指定的檔案中載入 Cookie。 此類的子類在 FileCookieJar 子類以及與 Web 瀏覽器的協作 一節中進行了說明。不應直接初始化此方法 - 請改用下面的子類。
在 3.8 版本中更改: filename 引數支援 類路徑物件。
- 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'))¶
建構函式的引數應該只作為關鍵字引數傳遞。blocked_domains 是一個域名序列,我們永遠不接受來自這些域名的 cookie,也不向這些域名返回 cookie。如果 allowed_domains 不是
None
,則它是一個僅接受和返回 cookie 的域名序列。secure_protocols 是可以新增安全 cookie 的協議序列。預設情況下,https 和 wss(安全 WebSocket)被認為是安全協議。對於所有其他引數,請參閱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
還提供了一些引數,允許對策略進行一些微調。
- class http.cookiejar.Cookie¶
此類表示 Netscape、RFC 2109 和 RFC 2965 cookie。不期望
http.cookiejar
的使用者構造自己的Cookie
例項。相反,如有必要,請在CookieJar
例項上呼叫make_cookies()
。
另請參閱
- 模組
urllib.request
使用自動 cookie 處理開啟 URL。
- 模組
http.cookies
HTTP cookie 類,主要用於伺服器端程式碼。
http.cookiejar
和http.cookies
模組彼此不依賴。- https://curl.se/rfc/cookie_spec.html
原始 Netscape cookie 協議的規範。儘管這仍然是主要的協議,但所有主要瀏覽器(和
http.cookiejar
)實現的“Netscape cookie 協議”僅與cookie_spec.html
中概述的協議略有相似之處。- RFC 2109 - HTTP 狀態管理機制
被 RFC 2965 廢棄。使用 Set-Cookie,版本為 1。
- RFC 2965 - HTTP 狀態管理機制
修復了錯誤的 Netscape 協議。使用 Set-Cookie2 代替 Set-Cookie。不常用。
- https://kristol.org/cookie/errata.html
對 RFC 2965 的未完成的勘誤。
RFC 2964 - HTTP 狀態管理的使用
CookieJar 和 FileCookieJar 物件¶
CookieJar
物件支援 迭代器 協議,用於迭代包含的 Cookie
物件。
CookieJar
具有以下方法
- CookieJar.add_cookie_header(request)¶
將正確的 Cookie 標頭新增到 request。
如果策略允許(即
CookieJar
的CookiePolicy
例項的rfc2965
和hide_cookie2
屬性分別為 true 和 false),則在適當的時候也會新增 Cookie2 標頭。request 物件(通常是
urllib.request.Request
例項)必須支援方法get_full_url()
、has_header()
、get_header()
、header_items()
、add_unredirected_header()
和屬性host
、type
、unverifiable
和origin_req_host
,如urllib.request
中所述。在 3.3 版本中更改:request 物件需要
origin_req_host
屬性。已刪除對已棄用方法get_origin_req_host()
的依賴。
- CookieJar.extract_cookies(response, request)¶
從 HTTP response 中提取 cookie,並將它們儲存在
CookieJar
中,如果策略允許的話。CookieJar
將在 response 引數中查詢允許的 Set-Cookie 和 Set-Cookie2 標頭,並根據需要儲存 cookie(受CookiePolicy.set_ok()
方法的批准)。response 物件(通常是對
urllib.request.urlopen()
或類似方法的呼叫結果)應支援info()
方法,該方法返回一個email.message.Message
例項。request 物件(通常是
urllib.request.Request
的例項)必須支援get_full_url()
方法以及host
,unverifiable
和origin_req_host
屬性,如urllib.request
文件所述。request 用於為 cookie 屬性設定預設值,並檢查是否允許設定 cookie。在 3.3 版本中更改:request 物件需要
origin_req_host
屬性。已刪除對已棄用方法get_origin_req_host()
的依賴。
- CookieJar.set_policy(policy)¶
設定要使用的
CookiePolicy
例項。
- CookieJar.make_cookies(response, request)¶
返回從 response 物件中提取的
Cookie
物件序列。關於 response 和 request 引數所需的介面,請參閱
extract_cookies()
的文件。
- CookieJar.clear([domain[, path[, name]]])¶
清除一些 cookie。
如果沒有引數呼叫,則清除所有 cookie。如果給定一個引數,則僅刪除屬於該 domain 的 cookie。如果給定兩個引數,則刪除屬於指定 domain 和 URL path 的 cookie。如果給定三個引數,則刪除具有指定的 domain、path 和 name 的 cookie。
如果不存在匹配的 cookie,則引發
KeyError
異常。
- CookieJar.clear_session_cookies()¶
丟棄所有會話 cookie。
丟棄所有具有 true
discard
屬性的包含的 cookie(通常是因為它們沒有max-age
或expires
cookie 屬性,或者顯式的discard
cookie 屬性)。對於互動式瀏覽器,會話結束通常對應於關閉瀏覽器視窗。請注意,
save()
方法不會儲存會話 cookie,除非您透過傳遞 true 的 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
異常。此外,可能會引發OSError
異常,例如,如果檔案不存在。
- FileCookieJar.revert(filename=None, ignore_discard=False, ignore_expires=False)¶
清除所有 cookie 並從儲存的檔案中重新載入 cookie。
FileCookieJar
例項具有以下公共屬性
- FileCookieJar.filename¶
用於儲存 cookie 的預設檔案的檔名。可以分配此屬性。
- FileCookieJar.delayload¶
如果為 true,則從磁碟延遲載入 Cookie。此屬性不應被賦值。這只是一個提示,因為它只會影響效能,而不會影響行為(除非磁碟上的 Cookie 正在更改)。
CookieJar
物件可能會忽略它。標準庫中包含的FileCookieJar
類都不會延遲載入 Cookie。
FileCookieJar 子類以及與 Web 瀏覽器的協作¶
提供了以下 CookieJar
子類,用於讀取和寫入。
- class http.cookiejar.MozillaCookieJar(filename=None, delayload=None, policy=None)¶
一個
FileCookieJar
,可以從磁碟載入 Cookie 並以 Mozillacookies.txt
檔案格式(也用於 curl 和 Lynx 和 Netscape 瀏覽器)儲存 Cookie 到磁碟。註解
這會丟失有關 RFC 2965 Cookie 的資訊,以及有關更新或非標準 Cookie 屬性(如
port
)的資訊。警告
如果你有丟失/損壞會帶來不便的 Cookie,請在儲存之前備份你的 Cookie(在載入/儲存往返過程中,可能會有一些細微之處導致檔案略有變化)。
另請注意,在 Mozilla 執行時儲存的 Cookie 將會被 Mozilla 覆蓋。
- class http.cookiejar.LWPCookieJar(filename=None, delayload=None, policy=None)¶
一個
FileCookieJar
,可以從磁碟載入 Cookie 並以與 libwww-perl 庫的Set-Cookie3
檔案格式相容的格式儲存 Cookie 到磁碟。如果你想將 Cookie 儲存在人類可讀的檔案中,這將非常方便。在 3.8 版本中更改: filename 引數支援 類路徑物件。
CookiePolicy 物件¶
實現 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()
返回 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()
。請注意,
domain_return_ok()
是為每個 cookie 域呼叫的,而不僅僅是為 request 域呼叫的。例如,如果請求域是"www.example.com"
,則該函式可能會同時使用".example.com"
和"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
類最有用的方法是透過從 DefaultCookiePolicy
繼承並覆蓋上述部分或全部方法。CookiePolicy
本身可以用作“空策略”,以允許設定和接收任何和所有 Cookie(這不太可能有用)。
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)¶
如果 domain 在設定或接收 Cookie 的阻止列表中,則返回
True
。
- DefaultCookiePolicy.is_not_allowed(domain)¶
如果 domain 不在設定或接收 Cookie 的允許列表中,則返回
True
。
DefaultCookiePolicy
例項具有以下屬性,這些屬性都從同名的建構函式引數初始化,並且都可以被賦值。
- DefaultCookiePolicy.rfc2109_as_netscape¶
如果為 true,則請求
CookieJar
例項將 RFC 2109 Cookie(即,在帶有版本 Cookie 屬性為 1 的 Set-Cookie 標頭中接收的 Cookie)降級為 Netscape Cookie,方法是將Cookie
例項的版本屬性設定為 0。預設值為None
,在這種情況下,當且僅當 RFC 2965 處理關閉時,RFC 2109 Cookie 才會被降級。因此,預設情況下會降級 RFC 2109 Cookie。
通用嚴格性開關
- DefaultCookiePolicy.strict_domain¶
不允許站點設定帶有國家程式碼頂級域名(如
.co.uk
,.gov.uk
,.co.nz
等)的雙元件域。這遠非完美,並且不能保證有效!
RFC 2965 協議嚴格性開關
- DefaultCookiePolicy.strict_rfc2965_unverifiable¶
遵循 RFC 2965 關於不可驗證事務的規則(通常,不可驗證事務是由於重定向或對託管在其他站點上的影像的請求而產生的)。如果此值為 false,則永遠不會根據可驗證性阻止 Cookie
Netscape 協議嚴格性開關
- 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.DomainLiberal¶
等價於 0(即,關閉所有上述 Netscape 域名嚴格性標誌)。
- DefaultCookiePolicy.DomainStrict¶
等價於
DomainStrictNoDots|DomainStrictNonDomain
。
Cookie 物件¶
Cookie
例項具有 Python 屬性,這些屬性大致對應於各種 Cookie 標準中指定的標準 Cookie 屬性。這種對應關係不是一一對應的,因為在分配預設值方面有複雜的規則,因為 max-age
和 expires
Cookie 屬性包含等效的資訊,並且 RFC 2109 Cookie 可能被 http.cookiejar
從版本 1 “降級” 為版本 0 (Netscape) Cookie。
除了在 CookiePolicy
方法中的罕見情況下,不應該需要給這些屬性賦值。該類不會強制內部一致性,因此如果您這樣做,您應該知道自己在做什麼。
- Cookie.version¶
整數或
None
。Netscape Cookie 的version
為 0。RFC 2965 和 RFC 2109 Cookie 的version
Cookie 屬性為 1。但是,請注意,http.cookiejar
可能會將 RFC 2109 Cookie “降級” 為 Netscape Cookie,在這種情況下,version
為 0。
- Cookie.name¶
Cookie 名稱(一個字串)。
- Cookie.domain¶
Cookie 域名(一個字串)。
- Cookie.path¶
Cookie 路徑(一個字串,例如
'/acme/rocket_launchers'
)。
- Cookie.secure¶
如果 Cookie 只能透過安全連線返回,則為
True
。
- Cookie.expires¶
自 epoch 以來以秒為單位的整數過期日期,或
None
。另請參閱is_expired()
方法。
- Cookie.discard¶
如果這是一個會話 Cookie,則為
True
。
- Cookie.rfc2109¶
如果此 Cookie 是作為 RFC 2109 Cookie 接收的(即,Cookie 出現在 Set-Cookie 標頭中,並且該標頭中 Version Cookie 屬性的值為 1),則為
True
。提供此屬性是因為http.cookiejar
可能會將 RFC 2109 Cookie “降級” 為 Netscape Cookie,在這種情況下,version
為 0。
- Cookie.port_specified¶
如果伺服器顯式指定了一個埠或一組埠(在 Set-Cookie / Set-Cookie2 標頭中),則為
True
。
- Cookie.domain_specified¶
如果伺服器顯式指定了一個域名,則為
True
。
- Cookie.domain_initial_dot¶
如果伺服器顯式指定的域名以點(
'.'
)開頭,則為True
。
Cookie 可能具有額外的非標準 Cookie 屬性。可以使用以下方法訪問它們
- Cookie.has_nonstandard_attr(name)¶
如果 Cookie 具有指定名稱的 Cookie 屬性,則返回
True
。
- Cookie.get_nonstandard_attr(name, default=None)¶
如果 Cookie 具有指定名稱的 Cookie 屬性,則返回其值。否則,返回 *default*。
- Cookie.set_nonstandard_attr(name, value)¶
設定指定名稱的 Cookie 屬性的值。
Cookie
類也定義了以下方法
- Cookie.is_expired(now=None)¶
如果 cookie 已經過了伺服器請求它過期的時刻,則返回
True
。如果給定了 now (自紀元以來的秒數),則返回 cookie 在指定時間是否已過期。
示例¶
第一個示例展示了 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(假設 Unix/Netscape 關於 cookie 檔案位置的約定)
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 或返回 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/")