【问题标题】:Python code to download tar.gz gives UnicodeDecodeError下载 tar.gz 的 Python 代码给出 UnicodeDecodeError
【发布时间】:2016-01-03 11:55:13
【问题描述】:

我想下载 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 中收到以下错误“文件”/usr/lib/python2.6/site-packages/resource_management/core/shell.py”,第 198 行 err_msg = Logger.filter_text(("执行 '%s' 返回 %d. %s") % (command_alias, code, out)) UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 1228: ordinal not in range(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 的 Execute 命令下载?

【问题讨论】:

  • 您已将问题标记为python-2.7,但错误显示为python-2.6。另外,resource_management 模块是什么?

标签: python unicode python-2.6 decoding


【解决方案1】:

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

#!/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 标头,即如果下载过早中断,您可能会得到部分文件。

【讨论】:

    【解决方案2】:

    堆栈跟踪非常明确。对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")))
    

    【讨论】:

      【解决方案3】:

      我会选择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())
      

      【讨论】:

      • 这对我有用。又一个问题,我想将java下载到/work位置,我该如何使用上面的代码呢?
      • 要么执行该目录中的代码,要么将 open() 调整为“/work/java.tar.gz”。你能回答“答案”吗?
      • 请注意,上面的代码需要~150Mb RAM,因为下载的文件是在一个块中读取的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-09
      • 1970-01-01
      • 2013-07-21
      • 2016-06-27
      相关资源
      最近更新 更多