Модуль http.cookiejar определяет классы для автоматической обработки файлов cookie HTTP. Он полезен для доступа к веб-сайтам, которым требуются небольшие фрагменты данных — файлы cookie, — которые HTTP-ответ веб-сервера сохраняет на компьютере клиента, а затем возвращает серверу в последующих HTTP-запросах.
Поддерживаются как обычный протокол файлов cookie Netscape, так и протокол, определённый в RFC 2965. Обработка по RFC 2965 по умолчанию отключена. Файлы cookie RFC 2109 разбираются как файлы cookie Netscape, а затем обрабатываются либо как файлы cookie Netscape, либо как файлы cookie RFC 2965 в соответствии с действующей «политикой». Обратите внимание, что подавляющее большинство файлов cookie в интернете — это файлы cookie Netscape. http.cookiejar стремится следовать фактически принятому протоколу файлов cookie Netscape (который существенно отличается от описанного в исходной спецификации Netscape), учитывая в том числе атрибуты файлов cookie max-age и port, введённые в RFC 2965.
Примечание
Различные именованные параметры в заголовках Set-Cookie и Set-Cookie2 (например, domain и expires) обычно называются атрибутами. Чтобы отличать их от атрибутов Python, в документации этого модуля для них используется термин атрибут файла cookie.
Модуль определяет следующее исключение:
exception http.cookiejar.LoadError
Экземпляры FileCookieJar вызывают это исключение, если не удаётся загрузить файлы cookie из файла. LoadError является подклассом OSError.
Изменено в версии 3.3: Ранее LoadError был подтипом IOError, который теперь является псевдонимом OSError.
Класс CookieJar хранит файлы cookie HTTP. Он извлекает файлы cookie из HTTP-запросов и возвращает их в HTTP-ответах. Экземпляры CookieJar автоматически удаляют содержащиеся в них файлы cookie по истечении срока действия. Подклассы также отвечают за сохранение файлов cookie в файл или базу данных и их извлечение оттуда.
class http.cookiejar.FileCookieJar(filename=None, delayload=None, policy=None)
policy — объект, реализующий интерфейс CookiePolicy. Описание остальных аргументов см. в документации соответствующих атрибутов.
Аргументы конструктора следует передавать только в виде именованных аргументов. blocked_domains — последовательность доменных имён, от которых мы никогда не принимаем файлы cookie и которым никогда их не возвращаем. Если allowed_domains не равно None, это последовательность единственных доменов, для которых мы принимаем и возвращаем файлы cookie. secure_protocols — последовательность протоколов, для которых можно добавлять защищённые файлы cookie. По умолчанию защищёнными считаются протоколы https и wss (защищённый WebSocket). Описание остальных аргументов см. в документации объектов CookiePolicy и DefaultCookiePolicy.
DefaultCookiePolicy реализует стандартные правила принятия и отклонения файлов cookie Netscape и RFC 2965. По умолчанию файлы cookie RFC 2109 (то есть файлы cookie, полученные в заголовке Set-Cookie с атрибутом файла cookie version, равным 1) обрабатываются по правилам RFC 2965. Однако если обработка RFC 2965 отключена или rfc2109_as_netscape равно True, экземпляр CookieJar «понижает» файлы cookie RFC 2109 до файлов cookie Netscape, устанавливая атрибут version экземпляра Cookie в 0. DefaultCookiePolicy также предоставляет некоторые параметры для тонкой настройки политики.
class http.cookiejar.Cookie
Этот класс представляет файлы cookie Netscape, RFC 2109 и RFC 2965. Предполагается, что пользователи http.cookiejar не будут создавать собственные экземпляры Cookie. Вместо этого при необходимости вызовите make_cookies() для экземпляра CookieJar.
Спецификация исходного протокола файлов cookie Netscape. Хотя этот протокол по-прежнему доминирует, «протокол файлов cookie Netscape», реализованный всеми основными браузерами (и http.cookiejar), лишь отдалённо напоминает описанный в cookie_spec.html.
Добавляет в request соответствующий заголовок Cookie.
Если это разрешено политикой (то есть если атрибуты rfc2965 и hide_cookie2 экземпляра CookiePolicy, используемого объектом CookieJar, имеют значения true и false соответственно), при необходимости также добавляется заголовок Cookie2.
Изменено в версии 3.3: Объекту request необходим атрибут origin_req_host. Зависимость от устаревшего метода get_origin_req_host() удалена.
CookieJar.extract_cookies(response, request)
Извлекает файлы cookie из HTTP-response и сохраняет их в CookieJar, если это разрешено политикой.
CookieJar ищет в аргументе response допустимые заголовки Set-Cookie и Set-Cookie2 и сохраняет файлы cookie, если это уместно (при условии одобрения метода CookiePolicy.set_ok()).
Объект request (обычно экземпляр urllib.request.Request) должен поддерживать метод get_full_url() и атрибуты host, unverifiable и origin_req_host, описанные в документации urllib.request. Запрос используется для установки значений по умолчанию для атрибутов файла cookie, а также для проверки возможности установки файла cookie.
Изменено в версии 3.3: Объекту request необходим атрибут origin_req_host. Зависимость от устаревшего метода get_origin_req_host() удалена.
Возвращает последовательность объектов Cookie, извлечённых из объекта response.
Описание требований к интерфейсам аргументов response и request см. в документации метода extract_cookies().
CookieJar.set_cookie_if_ok(cookie, request)
Устанавливает файл cookie Cookie, если политика это разрешает.
CookieJar.set_cookie(cookie)
Устанавливает файл cookie Cookie, не проверяя по политике, следует ли его устанавливать.
CookieJar.clear([domain[, path[, name]]])
Удаляет некоторые файлы cookie.
При вызове без аргументов удаляются все файлы cookie. Если передан один аргумент, удаляются только файлы cookie, относящиеся к этому домену. Если переданы два аргумента, удаляются файлы cookie, относящиеся к указанным домену и URL-пути. Если переданы три аргумента, удаляется файл cookie с указанными доменом, путём и именем.
Вызывает KeyError, если подходящего файла cookie нет.
CookieJar.clear_session_cookies()
Удаляет все сеансовые файлы cookie.
Удаляет все содержащиеся файлы cookie, у которых атрибут discard имеет значение true (обычно потому, что у них отсутствовал атрибут файла cookie max-age или expires либо был явно задан атрибут файла cookie discard). В интерактивных браузерах окончание сеанса обычно соответствует закрытию окна браузера.
Обратите внимание, что метод save() в любом случае не сохраняет сеансовые файлы cookie, если только вы явно не запросите это, передав аргумент ignore_discard со значением true.
FileCookieJar реализует следующие дополнительные методы:
Этот базовый класс вызывает NotImplementedError. Подклассы могут не реализовывать этот метод.
filename — имя файла, в котором нужно сохранить файлы cookie. Если filename не указан, используется self.filename (по умолчанию — значение, переданное конструктору, если оно есть); если self.filename равно None, вызывается ValueError.
ignore_discard: сохранять даже файлы cookie, помеченные для удаления. ignore_expires: сохранять даже файлы cookie с истёкшим сроком действия.
Если файл уже существует, он перезаписывается, и все содержащиеся в нём файлы cookie удаляются. Сохранённые файлы cookie можно восстановить позже с помощью методов load() или revert().
Указанный файл должен иметь формат, поддерживаемый классом, иначе будет вызвано исключение LoadError. Также может быть вызвано исключение OSError, например, если файл не существует.
Изменено в версии 3.3: Ранее вызывалось исключение IOError, теперь оно является псевдонимом OSError.
Удаляет все файлы cookie и повторно загружает их из сохранённого файла.
revert() может вызывать те же исключения, что и load(). В случае ошибки состояние объекта не изменится.
Экземпляры FileCookieJar имеют следующие общедоступные атрибуты:
FileCookieJar.filename
Имя файла по умолчанию для хранения файлов cookie. Этому атрибуту можно присвоить значение.
FileCookieJar.delayload
Если значение равно true, файлы cookie загружаются с диска лениво. Этому атрибуту не следует присваивать значение. Это лишь подсказка, поскольку она влияет только на производительность, но не на поведение (если только файлы cookie на диске не меняются). Объект CookieJar может её игнорировать. Ни один из классов FileCookieJar, включённых в стандартную библиотеку, не загружает файлы cookie лениво.
Подклассы FileCookieJar и взаимодействие с веб-браузерами
Для чтения и записи предоставляются следующие подклассы CookieJar.
class http.cookiejar.MozillaCookieJar(filename=None, delayload=None, policy=None)
FileCookieJar, который может загружать файлы cookie с диска и сохранять их на диск в формате файла cookies.txt Mozilla (который также используется curl и браузерами Lynx и Netscape).
Примечание
При этом теряется информация о файлах cookie RFC 2965, а также о новых или нестандартных атрибутах файлов cookie, таких как port.
Предупреждение
Если у вас есть файлы cookie, потеря или повреждение которых доставит неудобства, перед сохранением сделайте их резервную копию (из-за некоторых тонкостей при цикле загрузки и сохранения файл может незначительно измениться).
Также обратите внимание: если сохранить файлы cookie во время работы Mozilla, Mozilla перезапишет их.
class http.cookiejar.LWPCookieJar(filename=None, delayload=None, policy=None)
FileCookieJar, который может загружать файлы cookie с диска и сохранять их на диск в формате, совместимом с форматом файла Set-Cookie3 библиотеки libwww-perl. Это удобно, если вы хотите хранить файлы cookie в файле, удобном для чтения.
Возвращает False, если cookie не следует отправлять с учётом домена cookie.
Этот метод служит для оптимизации. Он избавляет от необходимости проверять каждый cookie с определённым доменом (что может потребовать чтения множества файлов). Если domain_return_ok() и path_return_ok() возвращают true, вся работа выполняется методом return_ok().
Если domain_return_ok() возвращает true для домена cookie, для пути cookie вызывается path_return_ok(). В противном случае для этого домена cookie методы path_return_ok() и return_ok() никогда не вызываются. Если path_return_ok() возвращает true, для полной проверки вызывается return_ok() с самим объектом Cookie. В противном случае для этого пути 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)
Возвращает False, если cookie не следует отправлять с учётом пути cookie.
Помимо реализации описанных выше методов, реализации интерфейса CookiePolicy должны также предоставлять следующие атрибуты, указывающие, какие протоколы и каким образом следует использовать. Всем этим атрибутам можно присваивать значения.
Не добавлять заголовок Cookie2 к запросам (наличие этого заголовка указывает серверу, что мы поддерживаем cookies RFC 2965).
Самый удобный способ определить класс CookiePolicy — создать подкласс DefaultCookiePolicy и переопределить некоторые или все описанные выше методы. Сам CookiePolicy можно использовать как «пустую политику», позволяющую устанавливать и получать любые cookies (это вряд ли будет полезно).
Объекты DefaultCookiePolicy
Реализует стандартные правила принятия и отправки cookies.
Поддерживаются cookies RFC 2965 и Netscape. Обработка 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, этот класс позволяет запрещать и разрешать доменам устанавливать и получать cookies. Также имеются переключатели строгости, позволяющие несколько ужесточить довольно свободные правила протокола Netscape (ценой блокировки некоторых безвредных cookies).
Предусмотрены списки запрещённых и разрешённых доменов (оба по умолчанию отключены). В установке и отправке cookies участвуют только домены, которых нет в списке запрещённых и которые присутствуют в списке разрешённых (если он включён). Используйте аргумент конструктора 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 — нет.
Задаёт последовательность разрешённых доменов или None.
DefaultCookiePolicy.is_not_allowed(domain)
Возвращает True, если domain отсутствует в списке разрешённых для установки или получения cookies.
Экземпляры DefaultCookiePolicy имеют следующие атрибуты. Все они инициализируются аргументами конструктора с такими же именами, и всем им можно присваивать значения.
DefaultCookiePolicy.rfc2109_as_netscape
Если значение истинно, запросить у экземпляра CookieJar преобразование cookies RFC 2109 в формат Netscape (то есть cookies, полученных в заголовке Set-Cookie с атрибутом cookie version со значением 1), путём присвоения атрибуту version экземпляра Cookie значения 0. Значение по умолчанию — None; в этом случае cookies RFC 2109 преобразуются тогда и только тогда, когда обработка RFC 2965 отключена. Поэтому по умолчанию cookies RFC 2109 преобразуются.
Общие переключатели строгости:
DefaultCookiePolicy.strict_domain
Не разрешать сайтам задавать двухкомпонентные домены с доменами верхнего уровня — кодами стран, например .co.uk, .gov.uk, .co.nz и т. д. Это решение далеко от совершенства, и его работа не гарантируется!
Следовать правилам RFC 2965 для непроверяемых транзакций (обычно непроверяемая транзакция возникает в результате перенаправления или запроса изображения, размещённого на другом сайте). Если значение ложно, cookies никогда не блокируются на основании проверяемости.
Переключатели строгости протокола Netscape:
DefaultCookiePolicy.strict_ns_unverifiable
Применять правила RFC 2965 для непроверяемых транзакций также и к cookies Netscape.
DefaultCookiePolicy.strict_ns_domain
Флаги, определяющие строгость правил сопоставления доменов для cookies Netscape. Допустимые значения см. ниже.
DefaultCookiePolicy.strict_ns_set_initial_dollar
Игнорировать cookies в заголовках Set-Cookie:, имена которых начинаются с '$'.
DefaultCookiePolicy.strict_ns_set_path
Не разрешать устанавливать cookies, путь которых не соответствует пути URI запроса.
strict_ns_domain — это набор флагов. Его значение формируется побитовым ИЛИ (например, DomainStrictNoDots|DomainStrictNonDomain означает, что установлены оба флага).
DefaultCookiePolicy.DomainStrictNoDots
При установке cookies «префикс хоста» не должен содержать точку (например, www.foo.bar.com не может установить cookie для .bar.com, поскольку www.foo содержит точку).
DefaultCookiePolicy.DomainStrictNonDomain
Cookies, для которых явно не указан атрибут cookie domain, можно отправлять только домену, совпадающему с доменом, установившим cookie (например, spam.example.com не будет отправлять cookies с example.com, у которых отсутствовал атрибут cookie domain).
DefaultCookiePolicy.DomainRFC2965Match
При установке cookies требовать полного соответствия домена правилам RFC 2965.
Для удобства предоставлены следующие атрибуты, представляющие собой наиболее полезные комбинации перечисленных выше флагов:
DefaultCookiePolicy.DomainLiberal
Эквивалентно 0 (то есть все перечисленные выше флаги строгости доменов Netscape отключены).
Атрибуты Python экземпляров Cookie в общих чертах соответствуют стандартным атрибутам cookie, определённым в различных стандартах cookies. Соответствие не является взаимно однозначным: существуют сложные правила назначения значений по умолчанию, атрибуты cookie max-age и expires содержат эквивалентную информацию, а cookies RFC 2109 могут быть преобразованы методом http.cookiejar из версии 1 в cookies версии 0 (Netscape).
Изменять эти атрибуты обычно не требуется, за исключением редких случаев в методе CookiePolicy. Класс не обеспечивает внутреннюю согласованность, поэтому при изменении атрибутов нужно понимать, что вы делаете.
Cookie.version
Целое число или None. Для cookies Netscape version равно 0. Для cookies RFC 2965 и RFC 2109 атрибут cookie version имеет значение 1. Однако обратите внимание, что http.cookiejar может преобразовать cookies RFC 2109 в cookies Netscape; в этом случае version равно 0.
Cookie.name
Имя cookie (строка).
Cookie.value
Значение cookie (строка) или None.
Cookie.port
Строка, представляющая порт или набор портов (например, «80» или «80,8080»), либо None.
Cookie.domain
Домен cookie (строка).
Cookie.path
Путь cookie (строка, например, '/acme/rocket_launchers').
Cookie.secure
True, если cookie следует отправлять только через защищённое соединение.
Cookie.expires
Целочисленная дата истечения срока действия в секундах с начала эпохи или None. См. также метод is_expired().
Cookie.discard
True, если это cookie сеанса.
Cookie.comment
Текстовый комментарий сервера, поясняющий назначение этого cookie, или None.
Cookie.comment_url
URL-адрес комментария сервера, поясняющего назначение этого cookie, или None.
Cookie.rfc2109
True, если этот cookie был получен как cookie RFC 2109 (то есть cookie пришёл в заголовке Set-Cookie, а значение атрибута cookie Version в этом заголовке было равно 1). Этот атрибут предусмотрен потому, что http.cookiejar может преобразовать cookies RFC 2109 в cookies Netscape; в этом случае version равно 0.
Cookie.port_specified
True, если сервер явно указал порт или набор портов (в заголовке Set-Cookie / Set-Cookie2).
Cookie.domain_specified
True, если сервер явно указал домен.
Cookie.domain_initial_dot
True, если домен, явно указанный сервером, начинался с точки ('.').
Cookies могут иметь дополнительные нестандартные атрибуты. Доступ к ним можно получить с помощью следующих методов:
Cookie.has_nonstandard_attr(name)
Возвращает True, если cookie имеет атрибут с указанным именем.
Cookie.get_nonstandard_attr(name, default=None)
Если cookie имеет атрибут с указанным именем, возвращает его значение. В противном случае возвращает default.
Cookie.set_nonstandard_attr(name, value)
Задаёт значение атрибута cookie с указанным именем.
True, если истёк срок действия cookie, установленный сервером. Если задано значение 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/")
В этом примере показано, как открыть URL-адрес, используя cookies Netscape, Mozilla или Lynx (предполагается, что используется расположение файла cookies, принятое в 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. Включите cookies RFC 2965, ужесточите правила для доменов при установке и отправке cookies Netscape и запретите некоторым доменам устанавливать cookies или получать их:
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/")