Использование файла cookies.txt с запросами Python

Я пытаюсь получить доступ к аутентифицированному сайту с помощью файла cookies.txt (сгенерированного с расширением Chrome) с запросами Python:

import requests, cookielib

cj = cookielib.MozillaCookieJar('cookies.txt')
cj.load()
r = requests.get(url, cookies=cj)

Он не выдает никаких ошибок или исключений, но неправильно выводит экран входа в систему. Тем не менее, я знаю, что мой файл cookie действителен, потому что я могу успешно загрузить свой контент с помощью wget. Любая идея, что я делаю неправильно?

Edit:

Я отслеживаю cookielib.MozillaCookieJar._really_load и могу убедиться, что файлы cookie правильно разобраны (т.е. они имеют правильные значения для токенов domain, path, secure и т.д.). Но по мере того, как транзакция по-прежнему приводит к форме входа в систему, кажется, что wget должен делать что-то дополнительное (поскольку для него работает тот же самый файл cookies.txt).

Ответ 1

MozillaCookieJar наследует от FileCookieJar, который имеет следующую конструкцию docstring в своем конструкторе:

Cookies are NOT loaded from the named file until either the .load() or
.revert() method is called.

Затем вам нужно вызвать метод .load().

Кроме того, как отметил Jermaine Xu, первая строка файла должна содержать строку # Netscape HTTP Cookie File или # HTTP Cookie File. Файлы, созданные плагином, которые вы используете, не содержат такой строки, поэтому вам нужно вставить ее самостоятельно. Я поднял соответствующую ошибку в http://code.google.com/p/cookie-txt-export/issues/detail?id=5

ИЗМЕНИТЬ

Файлы cookie сеанса сохраняются с 0 в 5-м столбце. Если вы не передадите метод ignore_expires=True to load(), все такие файлы cookie будут удалены при загрузке из файла.

Файл session_cookie.txt:

# Netscape HTTP Cookie File
.domain.com TRUE    /   FALSE   0   name    value

Python script:

import cookielib

cj = cookielib.MozillaCookieJar('session_cookie.txt')
cj.load()
print len(cj)

Вывод: 0

РЕДАКТИРОВАТЬ 2

Хотя нам удалось получить куки в банку выше, они впоследствии отбрасываются на cookielib, потому что они все еще имеют значение 0 в атрибут expires. Чтобы предотвратить это, мы должны установить время истечения срока в следующее будущее:

for cookie in cj:
    # set cookie expire date to 14 days from now
    cookie.expires = time.time() + 14 * 24 * 3600

РЕДАКТИРОВАТЬ 3

Я проверил как wget, так и curl, и оба используют время 0 expiry, чтобы обозначить куки сессии, что означает, что это стандарт de facto. Однако реализация Python использует пустую строку для той же цели, поэтому проблема возникает в вопросе. Я думаю, что поведение Python в этом отношении должно соответствовать тому, что делают wget и curl, и почему я поднял ошибку в http://bugs.python.org/issue17164
Отмечу, что замена 0 пустых строк в 5-м столбце входного файла и передача ignore_discard=True в load() является альтернативным способом решения проблемы (в этом случае не нужно менять время истечения срока действия).

Ответ 2

Наконец-то я нашел способ заставить его работать (я понял эту идею, посмотрев curl verbose ouput): вместо загрузки файлов cookie из файла я просто создал dict с требуемыми парами value/name

cd = {'v1': 'n1', 'v2': 'n2'}
r = requests.get(url, cookies=cd)

и он работал (хотя он не объясняет, почему предыдущий метод не выполнял). Спасибо за всю помощь, это очень понравилось.