Содержание страницы
20.21. cookielib – Обработка cookie для HTTP-клиентов¶cookielib – Cookie handling for HTTP clients
Примечание
Модуль cookielib в Python 3 переименован в http.cookiejar. Инструмент 2to3 при преобразовании исходного кода в Python 3 автоматически адаптирует импорты.
Новое в версии 2.4.
Исходный код: Lib/cookielib.py
Модуль cookielib определяет классы для автоматической обработки HTTP куки. Он полезен для доступа к веб-сайтам, которые требуют, чтобы небольшие фрагменты данных – куки – устанавливались на клиентской машине HTTP-ответом от веб-сервера, а затем возвращались серверу в последующих HTTP-запросах.
Обрабатываются как обычный протокол cookie Netscape, так и протокол, определённый в RFC 2965. Обработка RFC 2965 по умолчанию отключена.
Cookie RFC 2109 разбираются как cookie Netscape и впоследствии обрабатываются либо как cookie Netscape, либо как cookie RFC 2965 в зависимости от действующей «политики».
Обратите внимание, что подавляющее большинство cookie в интернете – это cookie Netscape.
cookielib пытается следовать фактическому протоколу cookie Netscape (который существенно отличается от того, что изложено в оригинальной спецификации Netscape), в том числе учитывая атрибуты cookie max-age и port, введённые в RFC 2965.
Примечание
Различные именованные параметры в заголовках Set-Cookie и
Set-Cookie2 (например, domain и expires) обычно называют
атрибутами. Чтобы отличать их от атрибутов Python, в документации этого модуля используется термин
cookie-атрибут.
Модуль определяет следующее исключение:
Экземпляры
FileCookieJarвозбуждают это исключение при невозможности загрузить куки из файла.
Предоставляются следующие классы:
policy – это объект, реализующий интерфейс
CookiePolicy.Класс
CookieJarхранит HTTP-куки. Он извлекает куки из HTTP-запросов и возвращает их в HTTP-ответах. ЭкземплярыCookieJarавтоматически удаляют устаревшие куки при необходимости. Подклассы также отвечают за сохранение и загрузку куки из файла или базы данных.
policy – это объект, реализующий интерфейс
CookiePolicy. Остальные аргументы описаны в документации соответствующих атрибутов.CookieJar, который может загружать куки из файла на диске и, возможно, сохранять их туда. Куки НЕ загружаются из указанного файла до тех пор, пока не будет вызван методload()илиrevert(). Подклассы этого класса описаны в разделе Подклассы FileCookieJar и взаимодействие с веб-браузерами.
Этот класс отвечает за принятие решения о том, следует ли принять каждый куки от сервера / вернуть его серверу.
Аргументы конструктора должны передаваться только как именованные аргументы. blocked_domains – это последовательность доменных имен, с которых мы никогда не принимаем куки и на которые никогда не отправляем их. allowed_domains, если не
None, – это последовательность доменов, единственных, для которых мы принимаем и возвращаем куки. По всем остальным аргументам смотрите документацию для объектовCookiePolicyиDefaultCookiePolicy.DefaultCookiePolicyреализует стандартные правила принятия/отклонения для куки Netscape и RFC 2965. По умолчанию, куки RFC 2109 (то есть куки, полученные в заголовке Set-Cookie с атрибутом version, равным 1) обрабатываются по правилам RFC 2965. Однако, если обработка RFC 2965 отключена илиrfc2109_as_netscapeравенTrue, куки RFC 2109 «понижаются» экземпляромCookieJarдо куков Netscape, путём установки атрибутаversionэкземпляраCookieв 0.DefaultCookiePolicyтакже предоставляет некоторые параметры для тонкой настройки политики.
Этот класс представляет куки Netscape, RFC 2109 и RFC 2965. Не предполагается, что пользователи
cookielibбудут создавать собственные экземплярыCookie. Вместо этого, при необходимости, следует вызыватьmake_cookies()для экземпляраCookieJar.
См. также
- Модуль
urllib2 Открытие URL с автоматической обработкой куки.
- Модуль
Cookie Классы HTTP-куки, пригодные в основном для серверного кода. Модули
cookielibиCookieне зависят друг от друга.- https://curl.haxx.se/rfc/cookie_spec.html
Спецификация оригинального протокола Netscape cookie. Хотя это всё ещё доминирующий протокол, «протокол Netscape cookie», реализованный всеми основными браузерами (и
cookielib), лишь отдалённо напоминает тот, что описан вcookie_spec.html.- RFC 2109 – Механизм управления состоянием HTTP
Заменено RFC 2965. Использует Set-Cookie с version=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 and FileCookieJar Objects
Объекты CookieJar поддерживают протокол итератора для итерации по
содержащимся объектам Cookie.
CookieJar имеет следующие методы:
Добавляет правильный заголовок Cookie к запросу.
Если политика разрешает (т.е. атрибуты
rfc2965иhide_cookie2экземпляраCookieJar'sCookiePolicyравны, соответственно, true и false), заголовок 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(), как описано вurllib2.
Извлекает куки из HTTP-ответа и сохраняет их в
CookieJar, где это разрешено политикой.CookieJarбудет искать допустимые заголовки Set-Cookie и Set-Cookie2 в аргументе ответа, и сохранять cookie соответствующим образом (с учётом одобрения методаCookiePolicy.set_ok()).Объект response (обычно результат вызова
urllib2.urlopen()или аналогичного) должен поддерживать методinfo(), который возвращает объект с методомgetallmatchingheaders()(обычно экземплярmimetools.Message).Объект request (обычно экземпляр
urllib2.Request) должен поддерживать методыget_full_url(),get_host(),unverifiable()иget_origin_req_host(), как описано вurllib2. Запрос используется для установки значений по умолчанию для атрибутов куки, а также для проверки, разрешена ли установка куки.
Устанавливает используемый экземпляр
CookiePolicy.
Возвращает последовательность объектов
Cookie, извлечённых из объекта ответа.Смотрите документацию к
extract_cookies()для описания интерфейсов, требуемых от аргументов ответа и запроса.
Устанавливает
Cookie, если политика разрешает это.
Устанавливает
Cookieбез проверки политики, следует ли его устанавливать.
Очищает некоторые куки.
Если вызван без аргументов, очищает все cookie. Если передан один аргумент, удаляются только cookie, принадлежащие этому домену. Если передано два аргумента, удаляются cookie, принадлежащие указанному домену и URL-пути. Если передано три аргумента, то удаляется cookie с указанными доменом, путём и именем.
Возбуждает
KeyError, если соответствующая cookie не найдена.
Удалить все сессионные куки.
Удаляет все содержащиеся cookie, у которых атрибут
discardимеет значение true (обычно потому, что у них не было атрибута cookiemax-ageилиexpires, либо был явный атрибут cookiediscard). Для интерактивных браузеров окончание сессии обычно соответствует закрытию окна браузера.Обратите внимание, что метод
save()в любом случае не сохраняет сессионные куки, если не указать иное, передав аргумент ignore_discard со значением True.
FileCookieJar реализует следующие дополнительные методы:
Сохраняет куки в файл.
Этот базовый класс вызывает исключение
NotImplementedError. Подклассы могут оставлять этот метод нереализованным.filename is the name of file in which to save cookies. If filename is not specified,
self.filenameis used (whose default is the value passed to the constructor, if any); ifself.filenameisNone,ValueErroris raised.ignore_discard: сохранять даже те куки, которые помечены к удалению. ignore_expires: сохранять даже куки с истекшим сроком действия.
Файл перезаписывается, если он уже существует, при этом удаляются все куки, которые он содержит. Сохраненные куки можно восстановить позже с помощью методов
load()илиrevert().
Загружает куки из файла.
Старые куки сохраняются, если они не перезаписываются вновь загруженными.
Аргументы такие же, как для
save().Указанный файл должен быть в формате, понятном классу, иначе будет возбуждено
LoadError. Кроме того, может быть возбужденоIOError, например, если файл не существует.
Очищает все куки и перезагружает куки из сохраненного файла.
revert()может возбуждать те же исключения, что иload(). В случае неудачи состояние объекта не изменится.
Экземпляры FileCookieJar имеют следующие открытые атрибуты:
Имя файла по умолчанию, в котором хранятся куки. Этому атрибуту можно присваивать значение.
Если истина, загружать куки с диска лениво. Этому атрибуту не следует присваивать значение. Это всего лишь подсказка, поскольку влияет только на производительность, а не на поведение (если только куки на диске не изменяются). Объект
CookieJarможет игнорировать её. Ни один из классовFileCookieJar, входящих в стандартную библиотеку, не загружает куки лениво.
20.21.2. Подклассы FileCookieJar и взаимодействие с веб-браузерами¶FileCookieJar subclasses and co-operation with web browsers
Следующие подклассы CookieJar предоставляются для чтения и
записи.
FileCookieJar, который может загружать и сохранять куки на диск в файловом формате Mozillacookies.txt(также используется браузерами Lynx и Netscape).Примечание
Версия 3 веб-браузера Firefox больше не записывает куки в формат файла
cookies.txt.Примечание
Это приводит к потере информации о куках RFC 2965, а также о более новых или нестандартных атрибутах куков, таких как
port.Предупреждение
Сделайте резервную копию ваших куки перед сохранением, если у вас есть куки, потеря или повреждение которых будут нежелательны (есть некоторые тонкости, которые могут привести к небольшим изменениям в файле при полном цикле загрузки/сохранения).
Также учтите, что куки, сохраненные во время работы Mozilla, будут перезаписаны Mozilla.
Объект
FileCookieJar, который может загружать и сохранять куки на диск в формате, совместимом с форматом файловSet-Cookie3библиотеки libwww-perl. Это удобно, если нужно хранить куки в файле, читаемом человеком.
20.21.3. Объекты CookiePolicy¶CookiePolicy Objects
Объекты, реализующие интерфейс CookiePolicy, имеют следующие
методы:
Возвращает логическое значение, указывающее, следует ли принять куки от сервера.
cookie – экземпляр
cookielib.Cookie. request – объект, реализующий интерфейс, описанный в документации дляCookieJar.extract_cookies().
Возвращает логическое значение, указывающее, следует ли вернуть куки серверу.
cookie – экземпляр
cookielib.Cookie. request – объект, реализующий интерфейс, описанный в документации дляCookieJar.add_cookie_header().
Возвращает false, если cookie не должны быть возвращены для данного домена cookie.
Этот метод – оптимизация. Он избавляет от необходимости проверять каждый куки для определённого домена (что может потребовать чтения многих файлов). Возврат true от
domain_return_ok()иpath_return_ok()оставляет всю работуreturn_ok().Если
domain_return_ok()возвращает true для домена куки,path_return_ok()вызывается для пути куки. В противном случаеpath_return_ok()иreturn_ok()никогда не вызываются для этого домена куки. Еслиpath_return_ok()возвращает true,return_ok()вызывается с объектомCookieдля полной проверки. В противном случаеreturn_ok()никогда не вызывается для этого пути куки.Обратите внимание, что
domain_return_ok()вызывается для каждого домена куки, а не только для домена запроса. Например, функция может вызываться как с".example.com", так и с"www.example.com", если домен запроса –"www.example.com". То же самое относится кpath_return_ok().Аргумент request описан в документации
return_ok().
Возвращает false, если cookie не должны быть возвращены для указанного пути cookie.
См. документацию
domain_return_ok().
Помимо реализации методов, описанных выше, реализации интерфейса
CookiePolicy должны также предоставлять следующие атрибуты,
указывающие, какие протоколы следует использовать и как. Все эти атрибуты
могут быть изменены (присвоены).
Реализация протокола Netscape.
Реализует протокол RFC 2965.
Не добавлять заголовок Cookie2 к запросам (наличие этого заголовка указывает серверу на то, что мы понимаем куки RFC 2965).
Самый удобный способ определить класс CookiePolicy – это создать подкласс
от DefaultCookiePolicy и переопределить некоторые (или все) методы
выше. Сам CookiePolicy может использоваться как «нулевая политика», позволяющая
устанавливать и принимать любые куки (вряд ли это будет полезно).
20.21.4. Объекты DefaultCookiePolicy¶DefaultCookiePolicy Objects
Реализует стандартные правила принятия и возврата куки.
Охватываются как куки RFC 2965, так и Netscape. Обработка 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,
этот класс позволяет блокировать и разрешать домены при установке и
получении куки. Также есть несколько переключателей строгости, которые позволяют
немного ужесточить довольно свободные правила протокола Netscape (ценой
блокировки некоторых безвредных куки).
Предоставляются чёрный и белый списки доменов (оба отключены по умолчанию). В установке и возврате 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 реализует следующие дополнительные методы:
Возвращает последовательность заблокированных доменов (в виде кортежа).
Устанавливает последовательность заблокированных доменов.
Возвращает, находится ли domain в чёрном списке для установки или получения куки.
Возвращает
Noneили последовательность разрешённых доменов (в виде кортежа).
Устанавливает последовательность разрешённых доменов или
None.
Возвращает, не находится ли domain в белом списке для установки или получения куки.
Экземпляры DefaultCookiePolicy имеют следующие атрибуты, все они инициализируются из аргументов конструктора с теми же именами, и всем им можно присваивать значения.
Если true, запросить, чтобы экземпляр
CookieJarпонижал cookie RFC 2109 (то есть cookie, полученные в заголовке Set-Cookie с атрибутом version cookie-attribute равным 1) до cookie Netscape, устанавливая атрибут версии экземпляраCookieв 0. Значение по умолчанию –None, и в этом случае cookie RFC 2109 понижаются только при отключённой обработке RFC 2965. Следовательно, по умолчанию cookie RFC 2109 понижаются.Новое в версии 2.5.
Общие переключатели строгости:
Не разрешает сайтам устанавливать двухкомпонентные домены с национальными доменами верхнего уровня, такими как
.co.uk,.gov.uk,.co.nzи т.д. Это далеко от совершенства и не гарантирует работу!
Переключатели строгости протокола RFC 2965:
Следовать правилам RFC 2965 для непроверяемых транзакций (обычно непроверяемая транзакция возникает в результате перенаправления или запроса изображения, размещённого на другом сайте). Если это False, куки никогда не блокируются на основе проверяемости.
Переключатели строгости протокола Netscape:
Применять правила RFC 2965 для непроверяемых транзакций даже к куки Netscape.
Флаги, указывающие, насколько строгими должны быть правила сопоставления доменов для cookies Netscape. Допустимые значения приведены ниже.
Игнорирует cookies в заголовках Set-Cookie, имена которых начинаются с
'$'.
Не разрешать установку куки, путь которых не соответствует URI запроса.
strict_ns_domain – это набор флагов. Его значение формируется путём
логического ИЛИ (например, DomainStrictNoDots|DomainStrictNonDomain означает,
что установлены оба флага).
При установке cookie «префикс хоста» не должен содержать точку (например,
www.foo.bar.comне может установить cookie для.bar.com, потому чтоwww.fooсодержит точку).
Cookie, которые не указали явно атрибут cookie
domain, могут быть возвращены только домену, равному домену, установившему cookie (например,spam.example.comне будут возвращены cookie отexample.com, у которых не было атрибута cookiedomain).
При установке куки требовать полного соответствия домена по RFC 2965.
Следующие атрибуты предоставлены для удобства и представляют собой наиболее полезные комбинации указанных выше флагов:
Эквивалентно 0 (то есть все указанные выше флаги строгости домена Netscape отключены).
Эквивалентно
DomainStrictNoDots|DomainStrictNonDomain.
20.21.5. Объекты Cookie¶Cookie Objects
Экземпляры Cookie имеют атрибуты Python, примерно соответствующие
стандартным атрибутам cookie, определённым в различных стандартах cookie. Это
соответствие не является взаимно однозначным, так как существуют сложные правила
присвоения значений по умолчанию, а также потому, что атрибуты cookie max-age и expires
содержат эквивалентную информацию, и потому что cookie RFC 2109 могут быть
'понижены' cookielib с версии 1 до версии 0 (Netscape).
Присваивание этим атрибутам должно быть необходимо только в редких
случаях, например в методе CookiePolicy. Класс не обеспечивает
внутренней согласованности, поэтому следует понимать, что делается при таком присваивании.
Целое число или
None. Cookie Netscape имеютversion0. Cookie RFC 2965 и RFC 2109 имеют атрибут cookieversionравный 1. Однако обратите внимание, чтоcookielibможет 'понижать' cookie RFC 2109 до cookie Netscape, и в этом случае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 был получен как cookie RFC 2109 (то есть cookie пришёл в заголовке Set-Cookie, и значение атрибута Version в этом заголовке было равно 1). Этот атрибут предоставлен, потому чтоcookielibможет 'понижать' cookie RFC 2109 до cookie Netscape, и в этом случаеversionравно 0.Новое в версии 2.5.
True, если порт или набор портов был явно указан сервером (в заголовке Set-Cookie / Set-Cookie2).
True, если домен был явно указан сервером.
True, если домен, явно указанный сервером, начинался с точки ('.').
Cookie могут иметь дополнительные нестандартные атрибуты cookie. Доступ к ним можно получить с помощью следующих методов:
Возвращает true, если cookie имеет атрибут с указанным именем.
Если cookie имеет указанный атрибут cookie, возвращает его значение. В противном случае возвращает default.
Устанавливает значение указанного атрибута cookie.
Класс Cookie также определяет следующий метод:
True, если срок действия cookie истёк (прошло время, указанное сервером для истечения). Если передан now (в секундах с начала эпохи), возвращается, истёк ли срок действия cookie на указанный момент времени.
20.21.6. Примеры¶Examples
Первый пример показывает наиболее распространённое использование cookielib:
import cookielib, urllib2
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")
Этот пример иллюстрирует, как открыть URL с использованием ваших куки Netscape, Mozilla или Lynx (предполагается соглашение Unix/Netscape о местоположении файла куки):
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/")
The next example illustrates the use of DefaultCookiePolicy. Turn on
RFC 2965 cookies, be more strict about domains when setting and returning
Netscape cookies, and block some domains from setting cookies or having them
returned:
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/")