UnicodeDecodeError:'ascii'编解码器无法解码位置2中的字节0xd1:序数不在范围内(128)

jel*_*tis 95 python django utf-8

我正在尝试使用一个非常大的数据集,其中包含一些非标准字符.根据工作规范,我需要使用unicode,但我很困惑.(并且很可能做错了.)

我使用以下命令打开CSV:

 15     ncesReader = csv.reader(open('geocoded_output.csv', 'rb'), delimiter='\t', quotechar='"')
Run Code Online (Sandbox Code Playgroud)

然后,我尝试用以下代码对其进行编码:

name=school_name.encode('utf-8'), street=row[9].encode('utf-8'), city=row[10].encode('utf-8'), state=row[11].encode('utf-8'), zip5=row[12], zip4=row[13],county=row[25].encode('utf-8'), lat=row[22], lng=row[23])
Run Code Online (Sandbox Code Playgroud)

我正在编码除了lat和lng之外的所有内容,因为那些需要发送到API.当我运行程序将数据集解析为我可以使用的内容时,我得到以下Traceback.

Traceback (most recent call last):
  File "push_into_db.py", line 80, in <module>
    main()
  File "push_into_db.py", line 74, in main
    district_map = buildDistrictSchoolMap()
  File "push_into_db.py", line 32, in buildDistrictSchoolMap
    county=row[25].encode('utf-8'), lat=row[22], lng=row[23])
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 2: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)

我想我应该告诉你我正在使用python 2.7.2,这是django 1.4上构建应用程序的一部分.我已经阅读了几个关于这个主题的帖子,但似乎都没有直接适用.任何帮助将不胜感激.

您可能还想知道导致该问题的一些非标准字符是Ñ并且可能是É.

ch3*_*3ka 140

Unicode不等于UTF-8.后者只是前者的编码.

你这样做是错误的.您正在读取 UTF-8 编码的数据,因此您必须将UTF-8编码的String 解码为unicode字符串.

因此,只需更换.encode.decode,它应该工作(如果您的.csv是UTF-8编码).

但是,没有什么可以感到羞耻的.我敢打赌,五分之五的程序员在开始理解这个问题时遇到了麻烦,如果不是更多;)

更新:如果您的输入数据不是 UTF-8编码,那么您必须.decode()使用适当的编码.如果没有给出任何内容,python会假定ASCII,这显然在非ASCII字符上失败.

  • 当然,但如果它是UTF8-*编码的*数据(我猜),那么`.decode('utf-8')`应该做的伎俩,也不是吗? (7认同)
  • 错误的原因是 Python 试图将其从默认编码 ASCII 自动解码,以便它可以按照他的指定将其编码为 UTF-8。由于数据不是有效的 ASCII,它不起作用。 (2认同)

khe*_*ana 81

只需在代码中添加以下行:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
Run Code Online (Sandbox Code Playgroud)

  • `AttributeError:模块'sys'没有属性'setdefaultencoding'在Python 3中似乎不起作用 (2认同)

scr*_*ard 19

对于Python 3用户.你可以做

with open(csv_name_here, 'r', encoding="utf-8") as f:
    #some codes
Run Code Online (Sandbox Code Playgroud)

它也适用于烧瓶:)

  • 这是我第一次帮助某人通过这里。知道我帮助了我感觉很好:) (2认同)

Tem*_*nle 9

出错的主要原因是python假定的默认编码是ASCII.因此,如果要编码的字符串数据encode('utf8')包含超出ASCII范围的字符,例如对于像'hgvcj터파크387'这样的字符串,则python会抛出错误,因为字符串不是预期的编码格式.

如果您使用的是早于3.5版的python版本,可靠的修复方法是将python假定的默认编码设置为utf8:

import sys
reload(sys)
sys.setdefaultencoding('utf8')
name = school_name.encode('utf8')
Run Code Online (Sandbox Code Playgroud)

这样python就能够预测字符串中超出ASCII范围的字符.

但是,如果您使用的是python版本3.5或更高版本,则reload()函数不可用,因此您必须使用解码修复它,例如

name = school_name.decode('utf8').encode('utf8')
Run Code Online (Sandbox Code Playgroud)

  • 更详细。人们通常会发现因果关系的细节很有帮助。顺便说一句,您的代码可以正常工作,没有任何贬义。 (2认同)

小智 5

对于 Python 3 用户:

将编码从“ascii”更改为“latin1”有效。

另外,您可以尝试使用以下代码片段读取前 10000 个字节来自动查找编码:

import chardet  
with open("dataset_path", 'rb') as rawdata:  
            result = chardet.detect(rawdata.read(10000))  
print(result)
Run Code Online (Sandbox Code Playgroud)


小智 5

检查您使用该locale命令使用的区域设置。如果不是en_US.UTF-8,请像这样更改:

sudo apt install locales 
sudo locale-gen en_US en_US.UTF-8    
sudo dpkg-reconfigure locales
Run Code Online (Sandbox Code Playgroud)

如果您没有权限这样做,您可以像这样运行所有 Python 代码:

PYTHONIOENCODING="UTF-8" python3 ./path/to/your/script.py
Run Code Online (Sandbox Code Playgroud)

或者在运行 Python 代码之前运行此命令

export PYTHONIOENCODING="UTF-8"
Run Code Online (Sandbox Code Playgroud)

将其设置在您运行它的外壳中。


就我而言,我使用的是POSIX默认的 Ubuntu 语言环境,而不是en_US.UTF-8,所以我看到了以下输出:

$ locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
Run Code Online (Sandbox Code Playgroud)

这导致 Python 以 ASCII 而不是 UTF-8 打开文件。

您可以检查 Python 正在使用哪个语言环境,如下所示:

>>> import locale
>>> locale.getpreferredencoding(False)
'ANSI_X3.4-1968'
Run Code Online (Sandbox Code Playgroud)

locale.getpreferredencoding(False)是当您不提供编码时调用的open()函数。输出应该是'UTF-8',但在我的例子中'ANSI_X3.4-1968',它是 ASCII 的某种变体