UnicodeEncodeError:“latin-1”编解码器无法编码字符

Posted

技术标签:

【中文标题】UnicodeEncodeError:“latin-1”编解码器无法编码字符【英文标题】:UnicodeEncodeError: 'latin-1' codec can't encode character 【发布时间】:2011-04-25 23:12:17 【问题描述】:

当我尝试将外来字符插入数据库时​​,可能导致此错误的原因是什么?

>>UnicodeEncodeError: 'latin-1' codec can't encode character u'\u201c' in position 0: ordinal not in range(256)

我该如何解决?

谢谢!

【问题讨论】:

db = mysqldb.connect(host="localhost", user = "root", passwd = "", db = "testdb", use_unicode=True, charset="utf8") 哇,@KyungHoonKim 你救了我的命!你去吧! 【参考方案1】:

我在使用 Python MySQLdb 模块时遇到了同样的问题。由于 MySQL 将允许您在文本字段中存储几乎任何您想要的二进制数据,而不管字符集如何,我在这里找到了我的解决方案:

Using UTF8 with Python MySQLdb

编辑:引用上述 URL 以满足第一条评论中的请求...

"UnicodeEncodeError:'latin-1' codec can't encode character ..."

这是因为 MySQLdb 通常会尝试将所有内容编码为 latin-1。 这可以通过在之后立即执行以下命令来解决 你已经建立了连接:

db.set_character_set('utf8')
dbc.execute('SET NAMES utf8;')
dbc.execute('SET CHARACTER SET utf8;')
dbc.execute('SET character_set_connection=utf8;')

“db”是MySQLdb.connect()的结果,“dbc”是MySQLdb.connect()的结果 db.cursor().

【讨论】:

建议在答案中提供链接项目的相关部分。额外阅读的链接很棒,但请尝试在您的答案中插入执行摘要:) 非常感谢,在尝试了 1000 次其他事情后,工作就像一个魅力。 只有 db.set_character_set('utf8') 才能解决问题【参考方案2】:

字符 U+201C 左双引号不存在于 Latin-1 (ISO-8859-1) 编码中。

出现在代码页 1252(西欧)中。这是基于 ISO-8859-1 的特定于 Windows 的编码,但会将额外字符放入 0x80-0x9F 范围内。代码页 1252 经常与 ISO-8859-1 混淆,这是一种令人讨厌但现在标准的 Web 浏览器行为,如果您将页面作为 ISO-8859-1 提供,浏览器会将它们视为 cp1252。但是,它们实际上是两种不同的编码:

>>> u'He said \u201CHello\u201D'.encode('iso-8859-1')
UnicodeEncodeError
>>> u'He said \u201CHello\u201D'.encode('cp1252')
'He said \x93Hello\x94'

如果您仅将数据库用作字节存储,则可以使用 cp1252 对 和 Windows 西方代码页中存在的其他字符进行编码。但是 cp1252 中不存在的其他 Unicode 字符仍然会导致错误。

您可以使用encode(..., 'ignore') 通过删除字符来抑制错误,但实际上在本世纪您应该在数据库和页面中都使用 UTF-8。这种编码允许使用任何字符。理想情况下,您还应该告诉 MySQL 您正在使用 UTF-8 字符串(通过设置数据库连接和字符串列上的排序规则),以便它可以进行不区分大小写的比较和排序。

【讨论】:

cp1252 不是 ISO-8859-1 的严格超集吗? IE。当浏览器收到 ISO-8859-1 页面时,它们可以将其渲染为 CP1252,因为无论如何不会有来自0x80-0x9F 范围内的任何字符。 不,字节 0x80–0x9F 在 ISO-8859-1 中确实有实际分配,这些分配被 cp1252 的添加覆盖,因此它不是超集。它们精确映射到 Unicode 字符 U+0080–U+009F,它们是控制字符的选择。它们是不经常使用的控制字符,这就是浏览器不使用它的原因,但是当您尝试将字节序列转换为 Unicode 时,这很烦人。 我唯一一次在编码为 ISO-8859-1 或 UTF-8 的文件中看到 U+0080-U+009F 范围内的字符是由一些小丑连接一堆文件,其中一些以 cp850 编码,然后将产生的混乱从“latin1”转码为 UTF-8。 html5 规范草案正在考虑将这种非常实用的浏览器行为(以及一大堆类似情况)神圣化——参见whatwg.org/specs/web-apps/current-work/multipage/…【参考方案3】:

最好的解决办法是

    将 mysql 的字符集设置为 'utf-8'

    喜欢这个评论(添加use_unicode=Truecharset="utf8"

    db = MySQLdb.connect(host="localhost", user = "root", passwd = "", db = "testdb", use_unicode=True, charset="utf8") – KyungHoon Kim Mar 2014 年 13 月 17 日 17:04

详情见:

class Connection(_mysql.connection):

    """MySQL Database Connection Object"""

    default_cursor = cursors.Cursor

    def __init__(self, *args, **kwargs):
        """

        Create a connection to the database. It is strongly recommended
        that you only use keyword parameters. Consult the MySQL C API
        documentation for more information.

        host
          string, host to connect

        user
          string, user to connect as

        passwd
          string, password to use

        db
          string, database to use

        port
          integer, TCP/IP port to connect to

        unix_socket
          string, location of unix_socket to use

        conv
          conversion dictionary, see MySQLdb.converters

        connect_timeout
          number of seconds to wait before the connection attempt
          fails.

        compress
          if set, compression is enabled

        named_pipe
          if set, a named pipe is used to connect (Windows only)

        init_command
          command which is run once the connection is created

        read_default_file
          file from which default client values are read

        read_default_group
          configuration group to use from the default file

        cursorclass
          class object, used to create cursors (keyword only)

        use_unicode
          If True, text-like columns are returned as unicode objects
          using the connection's character set.  Otherwise, text-like
          columns are returned as strings.  columns are returned as
          normal strings. Unicode objects will always be encoded to
          the connection's character set regardless of this setting.

        charset
          If supplied, the connection character set will be changed
          to this character set (MySQL-4.1 and newer). This implies
          use_unicode=True.

        sql_mode
          If supplied, the session SQL mode will be changed to this
          setting (MySQL-4.1 and newer). For more details and legal
          values, see the MySQL documentation.

        client_flag
          integer, flags to use or 0
          (see MySQL docs or constants/CLIENTS.py)

        ssl
          dictionary or mapping, contains SSL connection parameters;
          see the MySQL documentation for more details
          (mysql_ssl_set()).  If this is set, and the client does not
          support SSL, NotSupportedError will be raised.

        local_infile
          integer, non-zero enables LOAD LOCAL INFILE; zero disables

        autocommit
          If False (default), autocommit is disabled.
          If True, autocommit is enabled.
          If None, autocommit isn't set and server default is used.

        There are a number of undocumented, non-standard methods. See the
        documentation for the MySQL C API for some hints on what they do.

        """

【讨论】:

这个答案需要更多的支持。这是一个干净的解决方案,清除了应用层不必要的编码开销。 太棒了!这正是我想要的 另外,如果mysql有emoji.etc,最好设置utf8mb4,参考what-is-the-difference-between-utf8mb4-and-utf8-charsets-in-mysql【参考方案4】:

我希望您的数据库至少是 UTF-8。然后在尝试将其放入数据库之前,您需要运行 yourstring.encode('utf-8')

【讨论】:

【参考方案5】:

您正在尝试使用无法描述该代码点的编码 ISO-8859-1 / Latin-1 存储 Unicode 代码点 \u201c。您可能需要更改数据库以使用 utf-8,并使用适当的编码存储字符串数据,或者您可能希望在存储内容之前清理输入;即使用something like Sam Ruby's excellent i18n guide。这谈到了windows-1252 可能导致的问题,并建议了如何处理它,以及示例代码的链接!

【讨论】:

【参考方案6】:

使用下面的 sn-p 将文本从拉丁文转换为英文

import unicodedata
def strip_accents(text):
    return "".join(char for char in
                   unicodedata.normalize('NFKD', text)
                   if unicodedata.category(char) != 'Mn')

strip_accents('áéíñóúü')

输出:

'阿依诺'

【讨论】:

【参考方案7】:

SQLAlchemy 用户可以简单地将他们的字段指定为convert_unicode=True

示例: sqlalchemy.String(1000, convert_unicode=True)

SQLAlchemy 将简单地接受 unicode 对象并将它们返回,处理编码本身。

Docs

【讨论】:

【参考方案8】:

Latin-1(又名ISO 8859-1)是单八位字节字符编码方案,您不能将\u201c)放入一个字节中。

您的意思是使用 UTF-8 编码吗?

【讨论】:

Latin-1 编码 特定 Unicode 字符,而不是那个。 \u201c 是否不能放入一个字节并不重要。 windows-1252 也是一个单字节编码方案,确实包括 \u201c. cp1253(又名 windows-1253)也是一个单字节字符编码方案,但 \u0391 适合一个字节(特别是字节 193)。你可能想看看that;人们发现它很有帮助。 Unicode 将 Latin-1/cp1253 字形合并为 16 位代码点。我很惊讶 cmets 似乎声称相反。【参考方案9】:

UnicodeEncodeError: 'latin-1' codec can't encode character '\u2013' in position 106: ordinal not in range(256)

解决方案 1: \u2013 - 谷歌字符含义以确定实际导致此错误的字符,然后您可以将字符串中的特定字符替换为其他字符,这是您正在使用的编码的一部分。

解决方案 2: 将字符串编码更改为包含字符串所有字符的编码。然后你可以打印那个字符串,它就可以正常工作了。

以下代码用于更改字符串的编码,借用自@bobince

 u'He said \u201CHello\u201D'.encode('cp1252')

【讨论】:

【参考方案10】:

最新版本的mysql.connector只有

db.set_charset_collation('utf8', 'utf8_general_ci')

不是

db.set_character_set('utf8') //This feature is not available

【讨论】:

【参考方案11】:

Python:您需要添加 # - * - 编码:UTF-8 - * - (去掉 * 周围的空格) 到python文件的第一行。然后将以下内容添加到要编码的文本中:.encode('ascii', 'xmlcharrefreplace')。这会将所有 unicode 字符替换为其 ASCII 等效字符。

【讨论】:

以上是关于UnicodeEncodeError:“latin-1”编解码器无法编码字符的主要内容,如果未能解决你的问题,请参考以下文章

UnicodeEncodeError: ‘latin-1‘ codec can‘t encode characters in position 9-13: ordinal not in range(2

UnicodeEncodeError: 'latin-1' codec can't encode characters in position 0-3: ordinal not

[已解决]报错:UnicodeEncodeError: 'latin-1' codec can't encode characters in position 80-81(代码

接口测试中读取excel中的请求数据含有中文问题,UnicodeEncodeError: 'latin-1' codec can't encode character '

UnicodeEncodeError: ‘latin-1‘ codec can‘t encode character ‘u672c‘ in position 102: Body (‘本‘) is n(

requests爬虫请求报错:UnicodeEncodeError: 'latin-1' codec can't encode character 'u2026(