【问题标题】:JSON loads fails on invaild escape characters [duplicate]JSON加载在无效的转义字符上失败[重复]
【发布时间】:2016-06-26 14:46:54
【问题描述】:

我从外部服务获取一个大数据文件,其中每一行都是一个 json 对象。但是,它包含多个十六进制字符,如 (\xef,\xa0,\xa9) 等和一些 unicode 字符,如 (\u2022) 。我基本上是在读取文件,如

with open(filename,'r') as fh:
    for line in fh:
        attr = json.loads(line)

我尝试将编码 utf-8 和 latin-1 提供给 open 方法,但 json 加载仍然失败。如果删除了无效字符,则加载工作正常,但我不想丢失任何数据。解决此问题的推荐方法是什么?

repr(line) 示例:

'{"product_type":"SHOES","recommended_browse_nodes":"361208011","item_name":["Citygate  960561 Ankle Boots Womens  Gray Grau (anthrazit 9) Size: 8 (42 EU)"],"product_description":[],"brand_name":"Citygate","manufacturer":"J H P\\xf6lking GmbH & Co KG","bullet_point":[],"department_name":"Women\\u2019s","size_name":"42 EU","material_composition":["Leather"]}\n'

json.loads 在 item_name 中的 \xf6 处失败,并带有 Invalid \escape: line 1 column 105 (char 104)。

【问题讨论】:

  • 您的文件要么是有效的 JSON,要么不是。你能给我们提供一个合适的样品吗? \u2022 是有效的 JSON 语法。如果您有带有\xef文字文本,那么这不是有效的JSON。如果这些是字节,请显示使用此类行的repr() 输出。
  • @MartijnPieters 添加了示例和错误。
  • 这不是一行,也不是repr()的输出。通过这种方式,我们无法确定 \xa0 是单个字节还是 4 个单独的字符。
  • 虽然错误消息确实暗示您在此处有文字文本而不是单个字节,但使得这个 invalid JSON.
  • @MartijnPieters 为 line 添加了 repr() 。它只有一行,为了便于阅读,我已经格式化。正如我所提到的,我无法控制文件内容。你能建议一种将像 \xa0 这样的文字转换为相应字符的方法吗?

标签: python json python-3.x


【解决方案1】:

您可以使用@Martijn 提到的正则表达式修复 JSON 字符串。这是一个详细的例子。

import re
import json

s = '{"product_type":"SHOES","recommended_browse_nodes":"361208011","item_name":["Citygate  960561 Ankle Boots Womens  Gray Grau (anthrazit 9) Size: 8 (42 EU)"],"product_description":[],"brand_name":"Citygate","manufacturer":"J H P\\xf6lking GmbH & Co KG","bullet_point":[],"department_name":"Women\\u2019s","size_name":"42 EU","material_composition":["Leather"]}\n'

xinvalid = re.compile(r'\\x([0-9a-fA-F]{2})')

def fix_xinvalid(m):
    return chr(int(m.group(1), 16))

def fix(s):
    return xinvalid.sub(fix_xinvalid, s)

print(json.loads(fix(s)))

和输出:

{'recommended_browse_nodes': '361208011', 'bullet_point': [], 'product_description': [], 'brand_name': 'Citygate', 'size_name': '42 EU', 'material_composition': ['Leather'], 'product_type': 'SHOES', 'item_name': ['Citygate  960561 Ankle Boots Womens  Gray Grau (anthrazit 9) Size: 8 (42 EU)'], 'department_name': 'Women’s', 'manufacturer': 'J H Pölking GmbH & Co KG'}

【讨论】:

  • \uhhhh 转义是完全有效的。只有\xhh 转义需要修复。
  • @MartijnPieters 哦,不知道。删除它们...
  • @MartijnPieters 是的,它确实给出了相同的结果
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-15
  • 1970-01-01
  • 2022-01-26
  • 2012-01-01
  • 2021-08-12
  • 1970-01-01
相关资源
最近更新 更多