如何在Python中以UTF-8编码将数据写入磁盘?

时间:2010-06-27 19:44:58

标签: python unicode utf-8

以下Python代码......

html_data = urllib2.urlopen(some_url).read()
f = codecs.open(filename, 'w', encoding='utf-8')
f.write(html_data)
f.close()

...有时会因UnicodeDecodeError ...

而失败
File "/.../lib/python2.6/codecs.py", line 686, in write
  return self.writer.write(data)
File "/.../lib/python2.6/codecs.py", line 351, in write
  data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 5605: ordinal not in range(128)

我的问题:

  • 如何确保我的urllib2.urlopen(some_url).read()来电始终返回UTF-8?
  • 我的codecs.open(...)通话是否有任何问题阻止它以UTF-8编码将数据存储到磁盘上?

2 个答案:

答案 0 :(得分:2)

问题不在于codecs.open - 它传递给.write一个字节字符串(给定其中的\xd0代码)在某些ISO-8859-*中明确编码或相关的编解码器。

urllib2.urlopen返回一个响应对象,除了类似文件的行为外,它还是一个额外的方法:

  

info() - 返回元信息   的页面,如标题,在   httplib.HTTPMessage的形式   实例(见Quick Reference to HTTP Headers

特别是Content-Type标题,对于类似文本的内容,应该有一个charset参数,指定它使用的编码,例如Content-Type: text/html; charset=ISO-8859-4。您需要解析并隔离charset并使用它将内容解码为Unicode(因此您的codecs.open ed文件类对象始终会获得write的unicode参数并正确地将它们写入utf-8)。

如果缺少charset,或者使用它来解码文本会导致错误(建议charset错误),作为救赎的最后希望,您可以尝试使用的Universal Encoding Detector为此目的的启发式(毕竟,网络上的许多页面都有可怕的元数据错误,以及破坏的HTML等等。)

答案 1 :(得分:1)

  1. AFAIK,你做不到。但是,您可以从headers / html中检测编码并重新编码。
  2. 我不知道。我一直使用二进制模式进行写作,它始终有效
  3. 示例:

    data = urlopen(uri).read().decode(encoding)
    f = open(file_name, 'wb')
    f.write(data.encode('utf-8'))
    f.close()