在Python Requests中使用cookies.txt文件

27 投票
5 回答
39450 浏览
提问于 2025-04-17 15:03

我正在尝试用一个 cookies.txt 文件(这个文件是用Chrome扩展生成的)来访问一个需要登录的网站,使用的是Python的Requests库:

import requests, cookielib

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

虽然没有报错或异常,但我却看到的是登录界面,这显然是不对的。不过我知道我的cookie文件是有效的,因为我用 wget 命令成功获取到了内容。你们觉得我哪里做错了呢?

补充:

我在追踪 cookielib.MozillaCookieJar._really_load,可以确认这些cookie被正确解析(也就是说,它们的 domainpathsecure 等值都是对的)。但是因为最后还是显示登录表单,看来 wget 可能做了其他一些事情(因为同样的 cookies.txt 文件在它那边是可以用的)。

5 个回答

5

这个对我有效:

from http.cookiejar import MozillaCookieJar
from pathlib import Path
import requests

cookies = Path('/Users/name/cookies.txt')
jar = MozillaCookieJar(cookies)
jar.load()
requests.get('https://path.to.site.com', cookies=jar)
<Response [200]>
12

我试着考虑了Piotr Dobrogost勇敢研究的关于MozillaCookieJar的所有内容,但还是没能解决问题。最后我受够了,干脆自己解析了那个该死的cookies.txt文件,现在一切都好了:

import re
import requests

def parseCookieFile(cookiefile):
    """Parse a cookies.txt file and return a dictionary of key value pairs
    compatible with requests."""

    cookies = {}
    with open (cookiefile, 'r') as fp:
        for line in fp:
            if not re.match(r'^\#', line):
                lineFields = line.strip().split('\t')
                cookies[lineFields[5]] = lineFields[6]
    return cookies

cookies = parseCookieFile('cookies.txt')

import pprint
pprint.pprint(cookies)

r = requests.get('https://example.com', cookies=cookies)

18

MozillaCookieJar 是从 FileCookieJar 继承而来的,后者在构造函数中有以下说明:

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 这样的字符串。你使用的插件生成的文件并不包含这样的字符串,所以你需要自己添加。我在这里提交了一个相关的bug:http://code.google.com/p/cookie-txt-export/issues/detail?id=5

编辑

会话cookie在第五列用0来表示。如果你在调用 load() 方法时没有传入 ignore_expires=True,那么所有这样的cookie在从文件加载时都会被丢弃。

文件 session_cookie.txt

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

Python脚本:

import cookielib

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

输出: 0

编辑 2

虽然我们成功地将cookie放入了上面的jar中,但它们随后会被 cookielib 丢弃,因为它们在 expires 属性中仍然是 0。为了防止这种情况,我们需要 设置 过期时间为将来的某个时间,像这样:

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

编辑 3

我检查了 wget 和 curl,它们都使用 0 作为过期时间来表示会话cookie,这意味着这是一个事实上的标准。然而,Python 的实现使用空字符串来达到同样的目的,因此在这个问题中出现了困扰。我认为 Python 在这方面的行为应该与 wget 和 curl 保持一致,这就是我在这里提交bug的原因:http://bugs.python.org/issue17164
我想补充的是,将输入文件第五列中的 0 替换为空字符串,并在调用 load() 时传入 ignore_discard=True 是解决这个问题的另一种方法(在这种情况下不需要更改过期时间)。

撰写回答