360

我有一个套接字服务器,它应该从客户端接收 UTF-8 有效字符。

问题是一些客户端(主要是黑客)正在通过它发送所有错误类型的数据。

我可以轻松区分真正的客户,但我将所有发送的数据记录到文件中,以便以后进行分析。

有时我会得到这样œ的字符导致UnicodeDecodeError错误。

我需要能够使用或不使用这些字符来制作字符串 UTF-8。


更新:

对于我的特殊情况,套接字服务是 MTA,因此我只希望接收 ASCII 命令,例如:

EHLO example.com
MAIL FROM: <john.doe@example.com>
...

我在 JSON 中记录了所有这些。

然后一些没有好心的人决定发送各种垃圾。

这就是为什么对于我的具体情况,去掉非 ASCII 字符是完全可以的。

4

10 回答 10

395

http://docs.python.org/howto/unicode.html#the-unicode-type

str = unicode(str, errors='replace')

或者

str = unicode(str, errors='ignore')

注意: 这将删除(忽略)有问题的字符,返回没有它们的字符串。

对我来说,这是理想的情况,因为我使用它来保护我的应用程序不允许的非 ASCII 输入。

或者:使用codecs模块中的 open 方法读取文件:

import codecs
with codecs.open(file_name, 'r', encoding='utf-8',
                 errors='ignore') as fdata:
于 2012-09-17T23:05:11.223 回答
129

将引擎从 C 更改为 Python 对我有用。

引擎是C:

pd.read_csv(gdp_path, sep='\t', engine='c')

“utf-8”编解码器无法解码位置 18 中的字节 0x92:无效的起始字节

引擎是 Python:

pd.read_csv(gdp_path, sep='\t', engine='python')

对我来说没有错误。

于 2018-02-12T17:08:35.830 回答
76

既然我已经迁移到 Python 3,这种类型的问题就出现了。我不知道 Python 2 只是简单地滚动文件编码的任何问题。

我发现了这个对差异的很好的解释,以及在上述方法都不适合我之后如何找到解决方案。

http://python-notes.curiousefficiency.org/en/latest/python3/text_file_processing.html

简而言之,要使 Python 3 的行为尽可能与 Python 2 相似,请使用:

with open(filename, encoding="latin-1") as datafile:
    # work on datafile here

但是,阅读文章,没有一种万能的解决方案。

于 2016-06-09T10:21:19.290 回答
35
>>> '\x9c'.decode('cp1252')
u'\u0153'
>>> print '\x9c'.decode('cp1252')
œ
于 2012-09-17T23:06:39.330 回答
34

首先,使用 get_encoding_type 获取文件的编码类型:

import os    
from chardet import detect

# get file encoding type
def get_encoding_type(file):
    with open(file, 'rb') as f:
        rawdata = f.read()
    return detect(rawdata)['encoding']

第二,使用以下类型打开文件:

open(current_file, 'r', encoding = get_encoding_type, errors='ignore')
于 2019-05-31T03:21:36.787 回答
29

我有同样的问题,UnicodeDecodeError我用这条线解决了它。不知道是否是最好的方法,但它对我有用。

str = str.decode('unicode_escape').encode('utf-8')
于 2017-03-13T11:19:57.020 回答
15

此解决方案在使用拉丁美洲口音(例如“ñ”)时效果很好。

我只是通过添加解决了这个问题

df = pd.read_csv(fileName,encoding='latin1')
于 2020-06-03T18:09:43.207 回答
7

我已经使用此代码解决了这个问题

df = pd.read_csv(path, engine='python')
于 2020-11-03T12:00:58.150 回答
4

以防万一有人遇到同样的问题。我正在将 vim 与YouCompleteMe一起使用,无法使用此错误消息启动 ycmd,我所做的是:export LC_CTYPE="en_US.UTF-8",问题消失了。

于 2014-04-10T11:26:24.183 回答
3

如果您需要更改文件,但不知道文件的编码,该怎么办?如果您知道编码与 ASCII 兼容并且只想检查或修改 ASCII 部分,则可以使用 surrogateescape 错误处理程序打开文件:

with open(fname, 'r', encoding="ascii", errors="surrogateescape") as f:
    data = f.read()
于 2018-03-11T12:45:14.750 回答