以下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编码将数据存储到磁盘上?答案 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)
示例:
data = urlopen(uri).read().decode(encoding)
f = open(file_name, 'wb')
f.write(data.encode('utf-8'))
f.close()