为什么Python说这个Netscape cookie文件不是';无效吗?

为什么Python说这个Netscape cookie文件不是';无效吗?,python,cookies,Python,Cookies,我正在编写一个解析器,并基于此,在获取HTML之前设置cookies。这是我的cookies.txt文件的内容: # Netscape HTTP Cookie File # http://curlm.haxx.se/rfc/cookie_spec.html # This file was generated by libcurl! Edit at your own risk. .scholar.google.com TRUE / FALSE 2147483647

我正在编写一个解析器,并基于此,在获取HTML之前设置cookies。这是我的
cookies.txt
文件的内容:

# Netscape HTTP Cookie File
# http://curlm.haxx.se/rfc/cookie_spec.html
# This file was generated by libcurl! Edit at your own risk.

.scholar.google.com     TRUE    /       FALSE   2147483647      GSP     ID=353e8f974d766dcd:CF=2
.google.com     TRUE    /       FALSE   1317124758      PREF    ID=353e8f974d766dcd:TM=1254052758:LM=1254052758:S=_biVh02e4scrJT1H
.scholar.google.co.uk   TRUE    /       FALSE   2147483647      GSP     ID=f3f18b3b5a7c2647:CF=2
.google.co.uk   TRUE    /       FALSE   1317125123      PREF    ID=f3f18b3b5a7c2647:TM=1254053123:LM=1254053123:S=UqjRcTObh7_sARkN
这是我用来获取HTML的代码:

import http.cookiejar
import urllib.request, urllib.parse, urllib.error

def get_page(url, headers="", params=""):
    filename = "cookies.txt"
    request = urllib.request.Request(url, None, headers, params)
    cookies = http.cookiejar.MozillaCookieJar(filename, None, None)
    cookies.load()
    cookie_handler = urllib.request.HTTPCookieProcessor(cookies)
    redirect_handler = urllib.request.HTTPRedirectHandler()
    opener = urllib.request.build_opener(redirect_handler,cookie_handler)
    response = opener.open(request)
    return response

start = 0
search = "Ricardo Altamirano"
results_per_fetch = 20
host = "http://scholar.google.com"
base_url = "/scholar"
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; U; ru; rv:5.0.1.6) Gecko/20110501 Firefox/5.0.1 Firefox/5.0.1'}
params = urllib.parse.urlencode({'start' : start,
                                 'q': '"' + search + '"',
                                 'btnG' : "",
                                 'hl' : 'en',
                                 'num': results_per_fetch,
                                 'as_sdt' : '1,14'})

url = base_url + "?" + params
resp = get_page(host + url, headers, params)
完整回溯是:

Traceback (most recent call last):
  File "C:/Users/ricardo/Desktop/Google-Scholar/BibTex/test.py", line 29, in <module>
    resp = get_page(host + url, headers, params)
  File "C:/Users/ricardo/Desktop/Google-Scholar/BibTex/test.py", line 8, in get_page
    cookies.load()
  File "C:\Python32\lib\http\cookiejar.py", line 1767, in load
    self._really_load(f, filename, ignore_discard, ignore_expires)
  File "C:\Python32\lib\http\cookiejar.py", line 1997, in _really_load
    filename)
http.cookiejar.LoadError: 'cookies.txt' does not look like a Netscape format cookies file
回溯(最近一次呼叫最后一次):
文件“C:/Users/ricardo/Desktop/Google Scholar/BibTex/test.py”,第29行,在
resp=获取页面(主机+url、标题、参数)
文件“C:/Users/ricardo/Desktop/Google Scholar/BibTex/test.py”,第8行,在get_页面中
cookies.load()
加载文件“C:\Python32\lib\http\cookiejar.py”,第1767行
self.\u真的\u加载(f、文件名、忽略\u放弃、忽略\u过期)
文件“C:\Python32\lib\http\cookiejar.py”,第1997行,实际加载
文件名)
http.cookiejar.LoadError:“cookies.txt”看起来不像Netscape格式的cookies文件

我已经到处寻找关于Netscape cookie文件格式的文档,但是我找不到任何显示问题的东西。是否需要包括新行?为了以防万一,我将行结尾更改为Unix样式,但这并没有解决问题。我能找到的最接近的规范是,它并没有向我表明我遗漏了什么。最后四行中的每一行字段都用制表符分隔,而不是空格,其他所有内容在我看来都是正确的。

我在您的示例代码或cookies.txt文件副本中没有发现明显错误的内容

我已经检查了的源代码,它抛出了您看到的异常

此方法所做的第一件事是读取指定文件的第一行(使用
f.readline()
),并使用它查找正则表达式模式
“#(Netscape)?HTTP Cookie文件”
。这就是您的文件失败的原因

看起来您的
cookies.txt
肯定会与该格式匹配,因此您看到的错误非常令人惊讶

请注意,您的文件在前面是用一个简单的命令打开的,因此它将以文本模式打开,并支持通用行结束,这意味着您在Windows上运行此命令并不重要。代码将看到
\n
以换行符结尾的字符串,而不管文件本身使用了什么换行符约定

在这种情况下,我要做的是再次检查文件的第一行是否正确。它需要包含“#HTTP Cookie文件”或“#Netscape HTTP Cookie文件”(仅限空格,单词之间无制表符,大写匹配)。使用python提示符测试这一点:

>>> f = open('cookies.txt')
>>> line = f.readline()
>>> line
'# Netscape HTTP Cookie File\n'
>>> import re
>>> re.search("#( Netscape)? HTTP Cookie File", line)
<_sre.SRE_Match object at 0x10fecfdc8>

在上面的示例pdb会话中,我使用了
步骤
下一步
命令的组合来验证正则表达式测试(
self.magic\u re.search(magic)
)是否真的通过了。

在我的场景中,需要对MozillaCookieJar进行两次修改(/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/)

  • 魔术头球

    您可以删除检查逻辑或添加我喜欢的魔术头

    #Netscape HTTP Cookie文件

  • 新的文件格式似乎允许您忽略过期

    vals = line.split("\t")
    if len(vals) == 7 :
        domain, domain_specified, path, secure, expires, name, value = vals
    if len(vals) == 6 :
        domain, domain_specified, path, secure, name, value = vals
        expires = None
    

  • 最后,我真的希望实现可以更新到新的更改。

    请在您的开发控制台中执行此操作

    copy('# Netscape HTTP Cookie File\n' + document.cookie.split(/; /g).map(e => e.replace('=', '\t')).map(e => window.location.hostname.replace('www.', '.') + '\tTRUE\t/\tFALSE\t-1\t' + e).join('\n'))
    

    Netscape格式的cookies将出现在您系统的剪贴板中:)

    回答得很好!(也是调试python的一个很好的例子)。我不知道我的系统上是否有其他更改,但代码目前运行,对
    cookies.txt
    没有任何更改。文件的第一行与您的相同,包括空格、制表符等。因此我不确定是什么问题引发了问题。@RicardoAltamirano只是一个猜测:文本编码的更改,例如,像非正式的utf-8
    \xef\xbb\xbf
    这样的主要BOM可能会造成这种影响,并且可能不是很明显,因为只有二进制内容发生了更改,但作为文本,它可能看起来是相同的。如果您以前使用
    open
    和以后使用
    编解码器,同样的想法可能会在代码中发生变化。open
    @naxa:我在回答中显示的
    open()
    f.readline()
    会话(在Python 2上)将轻松显示任何此类代码点。IIRC一个UTF-8 BOM仍然是从
    codecs.open()
    io.open()
    文件对象返回的Unicode值的一部分,并且在任何情况下,指示符号
    u'
    Unicode字符串文字都将是一个死赠品。那就不用猜测了!除了,虽然这是,但值得检查磁盘空间是否为0,这通常是意外的,可能会导致一些奇怪的情况。在有人(AOL?)破坏历史之前,它曾经托管在netscape.com上。更新的规范与Set-Cookie2一样。对于任何感兴趣的人,实际上你可以执行“cookies.save(cookie\u file,ignore\u discard=True,ignore\u expires=True)”来创建一个有效的cookie文件作为实例,与无效的cookies.txt进行比较。逐行或逐字节比较,逐行删除,最终会找到原因。
    copy('# Netscape HTTP Cookie File\n' + document.cookie.split(/; /g).map(e => e.replace('=', '\t')).map(e => window.location.hostname.replace('www.', '.') + '\tTRUE\t/\tFALSE\t-1\t' + e).join('\n'))