从dictreader转换非ASCII字符为ASCII
File "F:...files.py", line 9, in files
for row in f:
File "C:\Python27\lib\csv.py", line 104, in next
row = self.reader.next()
File "C:\Python27\lib\codecs.py", line 684, in next
return self.reader.next()
File "C:\Python27\lib\codecs.py", line 615, in next
line = self.readline()
File "C:\Python27\lib\codecs.py", line 530, in readline
data = self.read(readsize, firstline=True)
File "C:\Python27\lib\codecs.py", line 477, in read
newchars, decodedbytes = self.decode(data, self.errors)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xfc in position 0: invalid start byte
关于Python和unicode/字符串的问题有很多。不过,之前的回答对我都没用。
首先,我用DictReader
打开一个文件,然后把每一行放进一个数组里。接着,把字典里的值转换成unicode。
第一步是获取数据。
f = csv.DictReader(open(filename,"r")
data = []
for row in f:
data.append(row)
第二步是从字典中获取字符串值,并替换掉重音符(这个是我从其他帖子上找到的)。
s = data[i].get('Name')
strip_accents(s)
def strip_accents(s):
try: s = unicode(s)
except: s = s.encode('utf-8')
s = unicodedata.normalize('NFKD', s).encode('ascii','ignore')
return s
我使用try和except是因为有些字符串有重音符,有些则没有。我搞不明白的是,unicode(s)
在没有重音符的type str
上能正常工作,但如果type str
有重音符,就会出错。
UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 11: ordinal not in range(128)
我见过关于这个的帖子,但那些答案都不管用。当我用type(s)检查时,它显示是<type 'str'>
。所以我尝试把文件当作unicode来读取。
f = csv.DictReader(codecs.open(filename,"r",encoding='utf-8'))
但一读取就出现了这个错误:
data = []
for row in f:
data.append(row)
这个错误是因为dictreader处理unicode的方式造成的吗?我该怎么解决这个问题呢?
更多测试。正如@univerio指出的,导致失败的一个原因是ISO-8859-1。
我把打开文件的语句修改为:
f = csv.DictReader(codecs.open(filename,"r",encoding="cp1252"))
结果出现了一个稍微不同的错误:
File "F:...files.py", line 9, in files
for row in f:
File "C:\Python27\lib\csv.py", line 104, in next
row = self.reader.next()
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 11: ordinal not in range(128)
使用基本的打开语句,并修改strip_accents(),像这样:
try: s = unicode(s)
except: s = s.decode("iso-8859-1").encode('utf8')
print type(s)
s = unicodedata.normalize('NFKD', s).encode('ascii','ignore')
return str(s)
打印出来的类型仍然是str,并且出错。
s = unicodedata.normalize('NFKD', s).encode('ascii','ignore')
TypeError: must be unicode, not str
根据这个Python: 从ISO-8859-1/latin1转换到UTF-8的帖子,修改为:
s = unicode(s.decode("iso-8859-1").encode('utf8'))
结果又出现了不同的错误:
except: s = unicode(s.decode("iso-8859-1").encode('utf8'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 11: ordinal not in range(128)
2 个回答
0
参考链接在这里: Unicode编码错误: 'ascii' 编码无法在位置0编码字符u'\xef': 序号不在范围(128)内,这是@Duncan的回答。
print repr(ch)
示例:
string = 'Ka\u011f KO\u011e52 \u0131 \u0130\u00f6\u00d6 David \u00fc K\u00dc\u015f\u015e \u00e7 \u00c7'
print (repr(string))
它输出:
'Kağ KOĞ52 ı İöÖ David ü KÜşŞ ç Ç'
1
我觉得这样做应该可以:
def strip_accents(s):
s = s.decode("cp1252") # decode from cp1252 encoding instead of the implicit ascii encoding used by unicode()
s = unicodedata.normalize('NFKD', s).encode('ascii','ignore')
return s
之所以用正确的编码打开文件没有成功,是因为 DictReader
似乎不能正确处理 Unicode 字符串。