22

我正在尝试使用cookies.txt带有 Python 请求的文件(使用 Chrome 扩展程序生成)访问经过身份验证的站点:

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文件适用于它)。

4

5 回答 5

15

MozillaCookieJar继承自FileCookieJarwhich 在其构造函数中具有以下文档字符串:

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 在第 5 列中保存为 0。如果您不传递ignore_expires=Trueload()方法,则在从文件加载时会丢弃所有此类 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因为它们在属性中仍然具有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过期时间来表示会话 cookie,这意味着它是事实上的标准。然而 Python 的实现使用空字符串来达到同样的目的,因此问题中提出了问题。我认为 Python 在这方面的行为应该与 wget 和 curl 所做的一致,这就是为什么我在http://bugs.python.org/issue17164
提出了这个错误 我会注意到0在第 5 列用空字符串替换 s输入文件并传递ignore_discard=Trueload()是解决问题的替代方法(在这种情况下无需更改到期时间)。

于 2013-02-07T19:47:16.233 回答
8

我尝试考虑 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)

于 2019-02-12T22:15:49.053 回答
3

这对我有用:

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]>
于 2021-03-24T06:10:16.457 回答
0

我尝试编辑 Tristan 答案以向其中添加一些信息,但似乎 SO edit q 已满,因此,我正在编写此答案,因为在将现有 cookie 与 python 请求一起使用时,我一直在苦苦挣扎。

  1. 首先,从 Chrome 中获取 cookie。最简单的方法是使用名为“cookies.txt”的扩展
https://chrome.google.com/webstore/detail/get-cookiestxt/bgaddhkoddajcdgocldbbfleckgcbcid/related
  1. 下载这些 cookie 后,使用以下代码确保您能够毫无问题地解析文件。
import re, requests, pprint
    
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 = re.findall(r'[^\s]+', line) #capturing anything but empty space
                try:
                    cookies[lineFields[5]] = lineFields[6]
                except Exception as e:
                    print (e)
          
    return cookies
    
cookies = parseCookieFile('cookies.txt') #replace the filename
pprint.pprint(cookies)
  1. 接下来,将这些 cookie 与 python 请求一起使用
x = requests.get('your__url', verify=False, cookies=cookies)
print (x.content)

这应该可以让您免于阅读不同的 SO 帖子并尝试那些对我没有用的 cookielib 和其他方法。

于 2022-01-06T06:50:19.840 回答
-1

我终于找到了一种让它工作的方法(我通过查看curl's 的详细输出得到了这个想法):我没有从文件中加载我的 cookie,而是简单地创建了一个dict带有所需value/name对的:

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

它起作用了(尽管它没有解释为什么以前的方法没有)。感谢所有帮助,非常感谢。

于 2013-02-07T22:21:53.757 回答