即使使用显式UTF8编码,Python的UTF8编码也会产生奇怪的结果

2024-10-05 13:18:10 发布

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

我正在解析一些JSON(特别是Amazon评论文件,Amazon公开提供)。我正在进行逐行解析,转换为Pandas DataFrame并即时插入到SQL。我发现了一些很奇怪的东西。我使用UTF-8打开json文件。当我用记事本打开文件时,我没有看到任何奇怪的符号。例如,review的子字符串:

The temperature control doesn’t hold to as tight a temperature as some of the others reported.

但当我分析它并检查字符串的内容时:

^{pr2}$

为什么会这样?我怎么看不懂?在

我当前的代码如下:

def parseJSON(path):
  g = io.open(path,'r',encoding='utf8')
  for l in g:
      yield eval(l)



for l in parseJSON(r"reviews.json"):
    for review in l["reviews"]:
        df = {}
        df[l["url"]] = review["review"]
        dfInsert = pd.DataFrame( list(df.items()), columns = ["url", "Review"])

出现故障的文件子集: http://www.filedropper.com/subset


Tags: 文件path字符串injsonurlamazondataframe
1条回答
网友
1楼 · 发布于 2024-10-05 13:18:10

首先,您不应该使用^{}解析来自不安全(联机)源的文本。如果数据在JSON中,则应该使用JSON解析器。这就是为什么JSON被发明的原因——提供安全的序列化和反序列化。在

在您的例子中,使用标准^{}模块中的^{}

import json

def parseJSON(path):
    return json.load(io.open(path, 'r', encoding='utf-8-sig'))

由于JSON文件包含一个BOM,所以应该使用知道如何对其进行剥离的编解码器,即^{}。在

如果文件每行包含一个JSON对象,则可以这样读取:

^{pr2}$

现在来回答为什么你看到的是doesn\xe2\x80\x99t而不是{}。如果将字节\xe2\x80\x99解码为UTF-8,则得到:

^{3}$

那是什么Unicode码位?在

>>> unicodedata.name(u'\u2019')
'RIGHT SINGLE QUOTATION MARK'

好了,现在在python2中eval()它会发生什么?首先,请注意,Unicode在Python2字符串领域并不是一等公民(Python3修复了这一点)。在

因此,eval尝试将字符串(Python 2中的一系列字节)解析为一个Python表达式:

>>> eval('"’"')
'\xe2\x80\x99'

请注意(在我使用UTF-8的控制台中),即使我键入,它也表示为一个3字节的序列。在

甚至说它应该是一个unicode

>>> eval('u"’"')
u'\xe2\x80\x99'

告诉Python如何解释source/string中后面的一系列字节,即编码是什么(参见PEP-263):

>>> eval('# encoding: utf-8\nu"’"')
u'\u2019'

相关问题 更多 >

    热门问题