ChatGPT解决这个技术问题 Extra ChatGPT

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

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

我使用以下方法打开 CSV:

 15     ncesReader = csv.reader(open('geocoded_output.csv', 'rb'), delimiter='\t', quotechar='"')

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

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])

我正在对除 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)

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

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

你的原始文件编码是什么?我觉得你应该按照原来的编码解码,然后转成utf 8
Encoding gives "'ascii' codec can't encode character … ordinal not in range(128)" 的可能副本 [Ed.:我敢肯定,还有大约无数其他人。]

I
Ingve

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

你做错了。您正在读取 UTF-8 编码的数据,因此您必须将 UTF-8 编码的字符串解码为 unicode 字符串。

所以只需将 .encode 替换为 .decode,它应该可以工作(如果您的 .csv 是 UTF-8 编码的)。

不过也没什么好丢脸的。我敢打赌,五分之三的程序员一开始都很难理解这一点,如果不是更多的话;)

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


错误的原因是 Python 试图自动将其从默认编码 ASCII 解码,以便它可以按照他的指定将其编码为 UTF-8。由于数据不是有效的 ASCII,因此它不起作用。
当然可以,但是如果它是 UTF8-encoded 数据(我猜),那么 .decode('utf-8') 应该可以解决问题,也不是?
当然,你可能是对的。我只是在解释为什么在这种情况下会出现该特定错误。
完美的!非常感谢。所以事实证明它是 .decode('latin-1') - 这是有道理的,因为是 Ñ 给了我问题。再次!谢谢!
您的解决方案适用于某些情况,但如果我使用它,我会收到另一个错误 'ascii' codec can't encode character u'\xf1' in position 2: ordinal not in range(128)
k
khelili miliana

只需将此行添加到您的代码中:

1.Python2

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

2.Python3

import sys
from importlib import reload
reload(sys)
sys.setdefaultencoding('utf-8')

`AttributeError:模块'sys'没有属性'setdefaultencoding'似乎在Python 3中不起作用
呜呜呜!这对我有帮助。
它适用于我的 Python 2.7,请注意,需要 reload(sys),否则无法访问 setdefaultencoding。
在许多 SO 问题中,这是唯一使它对我有用的东西。非常感谢!
名称“重新加载”未定义
S
Skrmnghrd

对于 Python 3 用户。你可以做

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

它也适用于烧瓶:)


这是我第一次在这里帮助别人。知道我帮助了我感觉很好:)
你也帮助了我:) 所有其他答案都不适用于文件阅读。现在我需要找出如何修复它以进行写作;)
你能把你的代码链接发给我吗?我会尽力帮助
谢谢!我忘了包括 'encoding="utf-8"' 部分!
T
Temi Fakunle

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

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

import sys
reload(sys)
sys.setdefaultencoding('utf8')
name = school_name.encode('utf8')

这样,python 将能够预测字符串中超出 ASCII 范围的字符。

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

name = school_name.decode('utf8').encode('utf8')

你的答案和我的有什么区别
更详细。人们经常发现因果细节很有帮助。顺便说一句,您的代码可以正常工作,无意贬损。
reload 在 Python 3 中可用,你只需要导入它。从 imp 导入重新加载
@Meow,但 Python 3 中没有 sys.setdefaultencoding 。因此,在兼容性 py2\py3 的上下文中,可以进行一些检查, sys.getdefaultencoding() 可能。非常感谢您对此事提出建议。 stackoverflow.com/questions/28127513/…
S
Stephen Rauch

对于 Python 3 用户:

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

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

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

B
Boris Verkhovskiy

我的电脑设置了错误的语言环境。

我第一次做

>>> import locale
>>> locale.getpreferredencoding(False)
'ANSI_X3.4-1968'

locale.getpreferredencoding(False)open() when you don't provide an encoding 调用的函数。输出应该是 'UTF-8',但在本例中是一些 variant of ASCII

然后我运行了 bash 命令 locale 并得到了这个输出

$ 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=

因此,我使用了默认的 Ubuntu 语言环境,这会导致 Python 以 ASCII 而不是 UTF-8 格式打开文件。我必须从 set my localeen_US.UTF-8

sudo apt install locales 
sudo locale-gen en_US en_US.UTF-8    
sudo dpkg-reconfigure locales

如果您无法在系统范围内更改语言环境,则可以像这样调用所有 Python 代码:

PYTHONIOENCODING="UTF-8" python3 ./path/to/your/script.py

或者做

export PYTHONIOENCODING="UTF-8"

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


A
Anish Varghese

如果您在创建或更新证书时运行 certbot 时遇到此问题,请使用以下方法

grep -r -P '[^\x00-\x7f]' /etc/apache2 /etc/letsencrypt /etc/nginx

该命令在评论的一个 .conf 文件中发现了有问题的字符“´”。删除它(您可以根据需要编辑评论)并重新加载 nginx 后,一切都恢复了。

来源:https://github.com/certbot/certbot/issues/5236


p
prosti

或者当您在 Python 中处理文本时,如果它是 Unicode 文本,请记下它是 Unicode。

设置 text=u'unicode text' 而不是仅设置 text='unicode text'

这在我的情况下有效。


S
Saeed

由于纬度和经度,使用编码 UTF 16 打开。

with open(csv_name_here, 'r', encoding="utf-16") as f:

J
Jose

它只通过使用参数'rb'读取二进制而不是'r'读取来工作


d
dom

在 Docker 容器中处理这个问题。可能是这种情况(对我而言),您只需要生成语言环境而无需执行任何其他操作:

sudo locale-gen en_US en_US.UTF-8

在某些情况下,这对我来说已经足够了,因为已经安装和配置了语言环境。如果您必须安装语言环境并对其进行配置,请将以下部分添加到您的 Dockerfile 中:

RUN apt update && apt install locales && \
    sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
    echo 'LANG="en_US.UTF-8"'>/etc/default/locale && \
    dpkg-reconfigure --frontend=noninteractive locales && \
    update-locale LANG=en_US.UTF-8

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8
ENV LC_ALL en_US.UTF-8

我是这样测试的:

cat <<EOF > /tmp/test.txt
++*=|@#|¼üöäàéàè!´]]¬|¢|¢¬|{ł|¼½{}}
EOF

python3
import pathlib; pathlib.Path("/tmp/test.txt").read_text()

K
Kavya Goyal

我在使用 Pickle 卸载时遇到了这个问题。尝试,

data = pickle.load(f,encoding='latin1')