当前位置: 首页 > 面试题库 >

Python-如何解决:“ UnicodeDecodeError:'ascii'编解码器无法解码字节”

冀耀
2023-03-14
问题内容
as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!

如何解决?

在其他基于python的静态博客应用中,中文帖子可以成功发布。像这个程序:http : //github.com/vrypan/bucket3。在我的网站http://bc3.brite.biz/中,中文帖子可以成功发布。


问题答案:

tl;dr / quick fix

  • 不要对Willy Nilly进行解码/编码
  • 不要以为你的字符串是UTF-8编码的
  • 尝试在代码中尽快将字符串转换为Unicode字符串
  • 解决你的语言环境:如何在Python 3.6中解决UnicodeDecodeError?
  • 不要试图使用快速reloadhack

Python 2.x中的Unicode Zen-完整版

在没有看到来源的情况下,很难知道根本原因,因此我将不得不大体讲一下。

UnicodeDecodeError: 'ascii' codec can't decode byte当你尝试将str包含非ASCII 的Python 2.x转换为Unicode字符串而不指定原始字符串的编码时,通常会发生这种情况。

简而言之,Unicode字符串是一种完全独立的Python字符串类型,不包含任何编码。它们仅保存Unicode 点代码,因此可以保存整个频谱中的任何Unicode点。字符串包含编码的文本,如UTF-8,UTF-16,ISO-8895-1,GBK,Big5等。字符串被解码为Unicode,而Unicodes被编码为字符串。文件和文本数据始终以编码的字符串传输。

Markdown模块的作者可能会使用unicode()(抛出异常的地方)作为其余代码的质量门-它会转换ASCII或将现有的Unicode字符串重新包装为新的Unicode字符串。Markdown作者无法得知传入字符串的编码,因此在传递给Markdown之前,将依赖你将字符串解码为Unicode字符串。

可以使用u字符串的前缀在代码中声明Unicode 字符串。例如

>>> my_u = u'my ünicôdé strįng'
>>> type(my_u)
<type 'unicode'>

Unicode字符串也可能来自文件,数据库和网络模块。发生这种情况时,你无需担心编码。

Gotchas

str即使不显式调用,也可能会发生从UnicodeUnicode的转换unicode()。

以下情况导致UnicodeDecodeError异常:

# Explicit conversion without encoding
unicode('€')

# New style format string into Unicode string
# Python will try to convert value string to Unicode first
u"The currency is: {}".format('€')

# Old style format string into Unicode string
# Python will try to convert value string to Unicode first
u'The currency is: %s' % '€'

# Append string to Unicode
# Python will try to convert string to Unicode first
u'The currency is: ' + '€'

例子

在下图中,你可以看到如何café根据终端类型以“ UTF-8”或“ Cp1252”编码方式对单词进行编码。在两个示例中,caf都是常规的ascii。在UTF-8中,é使用两个字节进行编码。在“ Cp1252”中,é是0xE9(它也恰好是Unicode点值(这不是巧合))。正确的decode()被调用,并成功转换为Python Unicode: 将字符串转换为Python Unicode字符串的图

在此图中,使用decode()进行调用ascii(与unicode()没有给出编码的调用相同)。由于ASCII不能包含大于的字节0x7F,这将引发UnicodeDecodeError异常:

将字符串转换为编码错误的Python Unicode字符串的图

The Unicode Sandwich

最好在代码中形成一个Unicode三明治,在该代码中,你将所有传入数据解码为Unicode字符串,使用Unicode,然后在输出时编码为strs。这使你不必担心代码中间的字符串编码。

输入/解码

源代码

如果你需要将非ASCII烘烤到源代码中,只需通过在字符串前面加上来创建Unicode字符串u。例如

u'Zürich'

为了允许Python解码你的源代码,你将需要添加一个编码标头以匹配文件的实际编码。例如,如果你的文件编码为“ UTF-8”,则可以使用:

# encoding: utf-8

仅当源代码中包含非ASCII时才需要这样做。

档案

通常从文件接收非ASCII数据。该io模块提供了一个TextWrapper,它使用给定即时解码文件encoding。你必须为文件使用正确的编码-不容易猜测。例如,对于UTF-8文件:

import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
     my_unicode_string = my_file.read() 

my_unicode_string然后适合传递给Markdown。如果UnicodeDecodeError从read()行开始,则你可能使用了错误的编码值。

CSV文件

Python 2.7 CSV模块不支持非ASCII字符。但是,https://pypi.python.org/pypi/backports.csv提供了帮助。

像上面一样使用它,但是将打开的文件传递给它:

from backports import csv
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
    for row in csv.reader(my_file):
        yield row

资料库
大多数Python数据库驱动程序都可以Unicode格式返回数据,但是通常需要一些配置。始终对SQL查询使用Unicode字符串。

MySQL

在连接字符串中添加:

charset='utf8',
use_unicode=True

例如

>>> db = MySQLdb.connect(host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")
PostgreSQL

加:

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)

HTTP

网页几乎可以采用任何编码方式进行编码。的Content-type报头应包含一个charset字段在编码暗示。然后可以根据该值手动解码内容。另外,Python-Requests在中返回Unicode response.text。

Manually

如果必须手动解码字符串,则可以简单地执行my_string.decode(encoding),其中encoding是适当的编码。此处提供了Python 2.x支持的编解码器:标准编码。同样,如果你得到了,UnicodeDecodeError则可能是编码错误。

The meat of the sandwich

像正常strs一样使用Unicode。

Output

stdout / printing

print通过stdout流写入。Python尝试在stdout上配置编码器,以便将Unicode编码为控制台的编码。例如,如果Linux shell localeen_GB.UTF-8,则输出将被编码为UTF-8。在Windows上,你将被限制为8位代码页。

错误配置的控制台(例如损坏的语言环境)可能导致意外的打印错误。PYTHONIOENCODING环境变量可以强制对stdout进行编码。

档案

就像输入一样,io.open可用于将Unicode透明地转换为编码的字节字符串。

数据库

用于读取的相同配置将允许直接编写Unicode

Python 3

Python 3不再比Python 2.x更具有Unicode功能,但是在该主题上的混淆却稍少一些。例如,常规str字符串现在是Unicode字符串,而旧字符串str现在是bytes。

默认编码为UTF-8,因此,如果你.decode()未提供任何编码的字节字符串,Python 3将使用UTF-8编码。这可能解决了50%的人们的Unicode问题。

此外,open()默认情况下以文本模式运行,因此返回已解码str(Unicode 编码)。编码来自你的语言环境,在Un * x系统上通常是UTF-8,在Windows机器上通常是8位代码页,例如Windows-1251。

为什么不应该使用 sys.setdefaultencoding('utf8')
这是一个令人讨厌的hack(有必要使用reload),它只会掩盖问题并阻碍你迁移到Python3.x。理解问题,解决根本原因并享受Unicode zen。请参阅为什么我们不应该在py脚本中使用sys.setdefaultencoding(“ utf-8”)?了解更多详情



 类似资料:
  • 如何修复它? 在其他一些基于python的静态博客应用程序中,可以成功发布中文帖子。例如此应用程序:http://github.com/vrypan/bucket3.在我的网站http://bc3.brite.biz/,可以成功发布中文帖子。

  • 问题内容: 我有一个套接字服务器,应该从客户端接收UTF-8有效字符。 问题是某些客户端(主要是黑客)正在通过它发送所有错误的数据。 我可以轻松地区分真正的客户端,但是我会将所有发送的数据记录到文件中,以便以后进行分析。 有时我会收到这样的字符œ,从而导致错误。 我需要使字符串UTF-8带有或不带有这些字符。 更新: 对于我的特殊情况,套接字服务是MTA,因此我只希望接收ASCII命令,例如: 我

  • 问题内容: 我想制作搜索引擎,并按照某些网络中的教程进行操作。我想测试解析html 它得到错误 我在网上看到了一些使用encode()的解决方案。但是我不知道如何在代码中插入encode()函数。谁能帮我? 问题答案: 在Python 3中,文件会以文本(解码为Unicode)的形式为您打开。您无需告诉BeautifulSoup要解码的编解码器。 如果数据解码失败,那是因为您没有告诉调用文件读取文

  • 我在尝试将字符串编码为UTF-8时遇到了一些问题。我尝试过很多方法,包括使用和,但我得到了错误: UnicodeDecodeError:“ascii”编解码器无法解码位置1中的字节0xef:序号不在范围内(128) 这是我的字符串: 我不知道出了什么问题,知道吗? 编辑:问题是打印字符串不能正确显示。此外,当我试图转换它时,这个错误:

  • 问题内容: 我有一个套接字服务器,应该从客户端接收UTF-8有效字符。 问题是某些客户端(主要是黑客)正在通过它发送所有错误的数据。 我可以轻松地区分真正的客户端,但是我会将所有发送的数据记录到文件中,以便以后进行分析。 有时我会得到这样的导致错误的字符。 我需要能够使带有或不带有这些字符的字符串UTF-8。 更新: 对于我的特殊情况,套接字服务是MTA,因此我只希望接收ASCII命令,例如: 我

  • 我有一个套接字服务器,它应该从客户端接收UTF-8有效字符。 问题是一些客户端(主要是黑客)正在通过它发送所有错误类型的数据。 我可以很容易地分辨出真正的客户机,但我会将发送的所有数据记录到文件中,以便以后进行分析。 有时我会遇到这样的字符,导致UnicodeDecodeError错误。 我需要能够使字符串UTF-8有或没有这些字符。 更新: 对于我的特殊情况,套接字服务是MTA,因此我只希望接收