【问题标题】:Python Load UTF-8 JSONPython 加载 UTF-8 JSON
【发布时间】:2014-04-18 01:01:05
【问题描述】:

我有以下 JSON(为简单起见,我只使用一个,但实际上有 100 个条目):

{
    "Active": false, 
    "Book": "US Derivat. London, Mike Übersax/Michael Jealous", 
    "ExpirationDate": "2006-10-12", 
    "Isin": "CH0013096497", 
    "IssueDate": "2001-10-09", 
    "KbForXMonths": "0", 
    "KbPeriodDay": "Period", 
    "KbType": "Prozent", 
    "KbYear": "0.5", 
    "Keyinvest_IssueRetro": "0.50%", 
    "Keyinvest_RecurringRetro": "1.00% pro rata temporis", 
    "Keyinvest_RetroPayment": "Every month", 
    "LastImportDate": "2008-12-31", 
    "LiberierungDate": "1900-01-01", 
    "NominalCcy": "USD", 
    "NominalStueck": "5,000", 
    "PrimaryCCR": "0", 
    "QuoteType": "Nominal", 
    "RealValor": "0", 
    "Remarks": "", 
    "RwbeProductId_CCR": "034900", 
    "RwbeProductId_EFS": "034900", 
    "SecName": "Cliquet GROI on Nasdaq", 
    "SecType": "EQ", 
    "SubscriptionEndDate": "1900-01-01", 
    "TerminationDate": "2003-10-19", 
    "TradingCcy": "USD", 
    "Valor": 1309649
}

我正在尝试读取此 JSON 以将其保存为 .csv(以便我可以将其导入数据库)

但是,当我尝试将此 JSON 数据写为 csv 时:

with codecs.open('EFSDUMP.csv', 'w', 'utf-8-sig') as csv_file:
    content_writer = csv.writer(csv_file, delimiter=',')
    content_writer.writerow(data.values())

我收到一个错误:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xdc' in position 25: ordinal not in range(128)

这是因为 JSON 中有一个变音符号(参见属性“Book”)。

我尝试像这样读取 JSON:

data = json.loads(open('EFSDUMP.json').read().decode('utf-8-sig'))

有趣的是:

print data

给我这个:

{u'PrimaryCCR': u'0', u'SecType': u'EQ', u'Valor': 1309649, u'KbType': u'Prozent', u'Book': u'US Derivat. London, Mike \xdcbersax/Michael Jealous', u'Keyinvest_RecurringRetro': u'1.00% pro rata temporis', u'TerminationDate': u'2003-10-19', u'RwbeProductId_CCR': u'034900', u'SubscriptionEndDate': u'1900-01-01', u'ExpirationDate': u'2006-10-12', u'Keyinvest_RetroPayment': u'Every month', u'Keyinvest_IssueRetro': u'0.50%', u'QuoteType': u'Nominal', u'KbYear': u'0.5', u'LastImportDate': u'2008-12-31', u'Remarks': u'', u'RealValor': u'0', u'SecName': u'Cliquet GROI on Nasdaq', u'Active': False, u'KbPeriodDay': u'Period', u'Isin': u'CH0013096497', u'LiberierungDate': u'1900-01-01', u'IssueDate': u'2001-10-09', u'KbForXMonths': u'0', u'NominalCcy': u'USD', u'RwbeProductId_EFS': u'034900', u'TradingCcy': u'USD', u'NominalStueck': u'5,000'}

很明显,元音变音变成了'\xdc'

但是当我这样做时:

print data['Book']

意思是我直接访问属性,我得到:

US Derivat. London, Mike Übersax/Michael Jealous

所以元音变音又是一个真正的元音变音。

我很确定 JSON 是没有 BOM 的 UTF-8(Notepad++ 声称如此)

我已经尝试了这里的所有建议,但没有成功: Python load json file with UTF-8 BOM header

如何正确读取 UTF-8 JSON 文件以便能够将其写入为 .csv?

非常感谢任何帮助。

Python 版本:2.7.2

【问题讨论】:

    标签: python json csv utf-8 byte-order-mark


    【解决方案1】:

    在 Python 2 中,csv 模块不支持编写 Unicode。您需要在此处手动对其进行编码,否则您的 Unicode 值是使用 ASCII 为您编码的(这就是您遇到编码异常的原因)。

    这也意味着您需要手动编写 UTF-8 BOM,但前提是您确实需要它。 UTF-8 只能以一种方式写入,读取 UTF-8 文件不需要字节顺序标记。 Microsoft 喜欢将其添加到文件中,以使他们的工具更容易检测文件编码的任务,但 UTF-8 BOM 实际上可能会使其他工具更难正常工作,因为它们不会忽略额外的初始字符。

    用途:

    with open('EFSDUMP.csv', 'wb') as csv_file:
        csv_file.write(codecs.BOM_UTF8)
        content_writer = csv.writer(csv_file)
        content_writer.writerow([unicode(v).encode('utf8') for v in data.values()])
    

    请注意,这会以任意(字典)顺序写入您的值。 unicode() 调用将在编码之前先将非字符串类型转换为 unicode 字符串。

    明确地说:您已经很好地加载了 JSON 数据。 CSV 写作对你来说失败了。

    【讨论】:

    • 非常感谢您澄清我失败的地方:)。但是我现在收到错误 content_writer.writerow(v.encode('utf8') for v in data.values()). _csv.Error: sequence expected. 请注意 JSON 中有一个布尔值和一个整数,因此编码可能在那里失败
    • @gta99:在这种情况下,您的 data 对象为空。确保您确实有一个非空的 data 字典。
    • data 不为空,但布尔值和整数值的编码似乎失败
    • @gta99:那将是一个不同的例外 (AttributeError: 'bool' object has no attribute 'encode')。如果您不只是字符串,请使用unicode(v).encode('utf8')。我确实看到您的示例输入中有一个整数值,我更新了代码来处理它。
    • @gta99:啊,确实,我的错。 Python 2 csv.writer.writerow() 无法处理迭代器。会更新。
    猜你喜欢
    • 2017-08-29
    • 2012-10-20
    • 2021-04-04
    • 1970-01-01
    • 2016-01-05
    • 2018-05-17
    • 1970-01-01
    相关资源
    最近更新 更多