python, codecs, file.writelines(), UnicodeDecodeError 中文解码错误
不知道怎么解决 UnicodeDecodeError
的问题:
我无法把文本写入文件,出现了 UnicodeDecodeError
,提到的字符是 â = '0xe2'
。
1) 确定在那个字符串里根本没有 â = '0xe2'
这个字符。
2) re.search
也找不到字符串中的 â
字符,而我正试图用 file.writelines(string)
写入。
3) 在打开文件时已经定义了 errors='replace'
,所以 file.writelines()
应该不会因为字符错误而报错。
File=codecs.open(fname, 'w','utf-8', errors='replace')
lines=smart_str( lines, 'utf-8', strings_only=False, errors='replace' )
# lines is 'some webpage text after BeautifulSoup.prettify which does not contain letter â ='0xe2', which is converted with Django smart_str to string'
FileA.writelines(lines) #gives UnicodeDecodeError : 'ascii' codec can't decode byte 0xe2 in position 9637: ordinal not in range(128).
myre = re.compile(r'0xe2', re.UNICODE) # letter â = '0xe2'
print re.search(myre, lines) #gives None
linessub=myre.sub('', lines)
print re.search(myre, linessub) #gives None
FileA.writelines(lines) #gives UnicodeDecodeError : 'ascii' codec can't decode byte 0xe2 in position 9637: ordinal not in range(128).
1 个回答
3
你正在使用 codecs.open
,所以你的文件对象需要的是 Unicode 字符串,而不是字节字符串。
使用这个函数的好处是,你不需要在写入文件之前自己对字符串进行编码。你只需要写 Unicode 字符串,文件对象会自动处理编码。
看起来 smart_str
返回的是 UTF-8 编码的字符串(因为你传给它了编码名称)。如果你把这个字符串传给期望 Unicode 的文件对象,它会先尝试把字节字符串解码回 Unicode。由于它不知道传入字符串的编码方式,所以会默认使用 ascii
。这就是错误产生的原因,因为这个字符串不是 ASCII,而是 UTF-8:
UnicodeDecodeError : 'ascii' codec can't decode...
所以,你要么跳过 smart_str
的编码步骤,直接写 Unicode 字符串到文件,或者把 codecs.open()
换成普通的 open()
,后者处理的是字节,因此需要已经编码好的字节字符串。
顺便说一下,你检查 0xE2 字符是否存在的方式是行不通的。首先,你使用 r'0xe2'
作为模式,这只是一个四个字符的字符串,而不是单个的 0xE2 字符。其次,对于这么简单的事情,你根本不需要 re
。你可以试试这个:
print '\xe2' in your_str