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