Python 要下载的代码 tar.gz 给出 UnicodeDecodeError

Python code to download tar.gz gives UnicodeDecodeError

我想下载 java,因此我使用了 shell 中的以下命令,它工作正常。

wget -P /data/ --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz

但是当我 运行 使用 python 相同的命令时,我得到一个错误。 这是我的 python 代码。

from resource_management import *

import os
import params
cmd = 'wget -P ' + params.java_tarball_path + ' --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz
print cmd
Execute(cmd, user=params.monarch_user, timeout=300)

我在 _call 中收到以下错误 "File "/usr/lib/python2.6/site-packages/resource_management/core/shell.py",第 198 行 err_msg = Logger.filter_text(("Execution of '%s' returned %d. %s") % (command_alias, code, out)) UnicodeDecodeError: 'ascii' 编解码器无法解码位置 1228 中的字节 0xe2:序号不在范围内 (128)"

我还在 python 中打印了要执行的命令,我觉得没问题。 “wget -P /data/ --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz

如何使用 python 的执行命令下载?

我会选择 urllib2requests 而不是 Execute

import urllib2
opener = urllib2.build_opener()
opener.addheaders.append(('Cookie', 'oraclelicense=accept-securebackup-cookie'))
f = opener.open('http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz')
with open('jdk-7u79-linux-x64.tar.gz', 'w+') as save:
     save.write(f.read())

堆栈跟踪非常明确。对 Logger.filter_text 的调用引发 UnicodeError。可能是因为 out 是一个 unicode。演示:

>>> "%s %s" % ("é", "é")   # works
'\xc3\xa9 \xc3\xa9'
>>> "%s %s" % ("é", u"é")  # doesn't work
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

您可能需要修改 resource_management/core/shell.py 中的代码并将 out 变量转换为 str:

Logger.filter_text(("Execution of '%s' returned %d. %s") % (command_alias, code, out.decode("utf-8")))

它看起来像是 resource_management 模块中的错误,它混合了字节串和 Unicode 文本。要解决此问题,您可以自己下载 tarball:

#!/usr/bin/env python2
import os
import urllib2
from contextlib import closing
from shutil import copyfileobj

url = 'http://example.com/tarball.tar.gz'
headers = {'Cookie': 'oraclelicense=accept-securebackup-cookie'}
with closing(urllib2.urlopen(urllib2.Request(url, headers=headers))) as response, \
     open(os.path.join('/data', url.rsplit('/', 1)[-1]), 'wb') as output_file:
    copyfileobj(response, output_file)

该代码不会将整个文件加载到内存中,因此它可能支持大文件。它不检查 Content-Length header 即,如果下载过早中断,您可能会得到部分文件。