Python 编码 - 无法解码为 utf8

2024-03-29 01:04:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个由外部程序填充的sqlite数据库。我试图用python读取数据。当我试图读取数据时,会出现以下错误:

操作错误:无法解码为UTF-8

如果我在sqlite manager中打开数据库,并使用内置的浏览和搜索功能查看违规记录中的数据,它看起来很好,但是如果我将表导出为csv,我会注意到违规记录中的字符英镑已变为

如果我在python中读取csv,那么有问题的记录中的英镑仍会被读取为,但这不是问题,我可以手动解析它。但是,我需要能够直接从数据库中读取数据,而无需转换为csv的中间步骤。

我在网上查找了一些类似问题的答案,到目前为止,我尝试设置“text_factory=str”,还尝试使用sqlite管理器将列的数据类型从文本更改为BLOB,但仍然会得到错误。

下面的代码导致操作错误:无法解码为UTF-8

conn = sqlite3.connect('test.db')
conn.text_factory = str
curr = conn.cursor()
curr.execute('''SELECT xml_dump FROM hands_1 LIMIT  5000  , 5001''')
row = curr.fetchone()

数据库中5000以上的所有记录都存在此字符问题,因此会产生错误。

感谢任何帮助。


Tags: csvtext程序数据库sqlitefactory错误记录
2条回答

Python试图通过将文本片段(作为字节存储在数据库中)转换为Pythonstr对象来提供帮助。为了进行这种转换,python必须猜测查询返回的每个字节(或字节组)代表的字母。默认猜测是一种称为utf-8的编码。显然,你的猜测是错的。

解决方案是给python一点提示,告诉他如何从字节到字母(即unicode字符)进行映射。你已经接近底线了

conn.text_factory = str

但是(基于您在上面注释中的响应),由于您使用的是python 3,str是默认的文本工厂,因此这一行对您没有任何新功能(请参见the docs)。

这一行的幕后操作是,python尝试使用str函数转换查询返回的字节,类似于:

your_string = str(the_bytes, 'utf-8') # actually uses `conn.text_factory`, not `str`

…但你需要一个不同的编码,其中'utf-8'是。由于无法更改str函数的默认编码,因此必须以其他方式模拟它。您可以使用一个名为alambda的一次性无名函数来实现以下目的:

conn.text_factory = lambda x: str(x, 'latin1')

现在,当数据库将字节传递给python时,python将尝试使用“latin1”方案而不是“utf-8”方案将它们映射到字母。当然,我不知道latin1是否是您数据的正确编码。实际上,你必须尝试一些编码才能找到正确的编码。我将首先尝试以下操作:

  • 'iso-8859-1'
  • 'utf-16'
  • 'utf-32'
  • 'latin1'

您可以找到一个更完整的列表here

另一种选择是简单地让从数据库中输出的字节保持为字节。这对你来说是否是个好主意取决于你的申请。您可以通过设置:

conn.text_factory = bytes

如果数据库中的文本实际上大部分是用UTF-8编码的,但您仍然看到这个错误(无法解码为UTF-8),那么问题可能是一行或多行有无效UTF-8的伪数据。默认情况下,Python的decode()函数在看到类似文本时抛出异常。如果您正处于这种情况,并且只想忽略这些错误,那么可以设置如下的text_factory

conn = sqlite3.connect('my-database.db')
conn.text_factory = lambda b: b.decode(errors = 'ignore')

相关问题 更多 >