将具有未知编码的文件从Python导入到MongoDB

6

我正在使用Python通过HTTP导入一个制表符分隔的文件。

在将行数据插入MongoDB之前,我会从字符串中删除斜杠、引号和引号。

无论数据的编码是什么,MongoDB都会抛出异常:

bson.errors.InvalidStringData: strings in documents must be valid UTF-8

为了解决这个问题,根据我所读的内容,我希望尽快地使用unicode()函数将行数据转换为Unicode。此外,我尝试调用decode()函数并将"unicode"作为第一个参数传递,但是遇到了以下错误:

LookupError: unknown encoding: unicode

从那里开始,我可以进行字符串操作,例如替换斜线、引号和引号。然后,在将数据插入MongoDB之前,使用str.encode('utf-8')函数将其转换为UTF-8。

问题:在转换为Unicode时,我收到了错误信息。

UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 1258: ordinal not in range(128)

遇到这种错误,我不确定该如何继续。

我的问题是:如果不知道文件的编码方式,如何成功导入数据并将其插入到要求UTF-8的MongoDB中?

非常感谢!


但是你说过“通过HTTP导入制表符分隔的文件”...那么“CSV”在其中扮演什么角色? - John Machin
1个回答

7

按照以下顺序尝试:

(0) 检查你删除反斜杠/引号等是否损坏了数据。什么是引号?请展示你的代码。请展示一份原始数据样本...使用print repr(sample_raw data),并将输出复制/粘贴到问题的编辑中。

(1) 有句古话:“如果文件的编码未知,或者声明为ISO-8859-1,则它是cp1252”...你从哪里得到这个信息?如果来自西欧、美洲或其他任何讲英语/法语/西班牙语的国家/地区,并且不是有效的UTF-8,则很可能是cp1252

[编辑2] 对于所有编码cp1250到cp1258,您的错误字节0x93解码为U+201C左双引号...文本是用什么语言写的? [/编辑2]

(2) 在保存文件(删除引号之前)后,在浏览器中打开文件:看起来合理吗?单击“查看/字符编码”时会看到什么?

(3) 尝试chardet

编辑带有更多建议:

一旦您知道编码是什么(假设它是cp1252):

(1) 将输入数据转换为Unicode:uc = raw_data.decode('cp1252')

(2) 处理Unicode数据(删除反斜杠/引号等):clean_uc = manipulate(uc)

(3) 您需要将您的数据作为utf8编码输出:to_mongo = clean_uc.encode('utf8')

注意1:您的错误消息说“无法解码位置1258处的字节0x93”... 1258个字节是一个相当长的文本块;这合理吗?您是否查看了它所抱怨的数据?如何查看?看到了什么?

注意2:请考虑阅读Python Unicode HOWTO此文章


@Joshua Burns:感谢您接受了这个答案,但是未来的读者会像我一样想知道结果是什么……cp1252还是其他什么? - John Machin
@Joshua Burns:抱歉,我不明白 "indeed" 的意思。我没有说它是 Latin-1。我说它很可能是 cp125X。Latin-1 不是 cp125X。你的错误字节0x93,在使用 Latin-1 解码时是一些奇怪的、在现实世界中从未见过的控制字符。 - John Machin
该文件最初是用英语编写的,并由外部来源提供。我猜想在某个阶段,一些数据变得损坏并且从未被修复。将文本编码为Latin-1解决了这种情况下的问题,尽管这意味着一个非现实的字符被表示出来。 - Joshua Burns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接