python - 如何反序列化分割后的json数据

标签 python json deserialization

我通过服务器发送事件流式传输数据并获取大约500.000个数据集,但我得到的不是一个json(500.000个数据集中的2个的示例)(这就是打开它的样子) gedit,所有问号均为\",所有新行均为\n):

data:{\"data\":[\"Kendrick\",\"Lamar\"]}\n\ndata:{\"data\":[\"David\",\"Bowie\"]}\n\n
... -

我的目标是将其放入数据库中。我实际上认为我把它放入字典中,然后从这里创建一个 pandas 数据框,我应该能够将它放入数据库中。但这最终会变得相当麻烦。我最终得到了这样的结果:

c1 = data_json[1:-1]
c2 = c1.replace('{data:{', '{\"data\":{')
c3 = c2.replace('}data:{', ', ')
c4 = '{' + c3 + '}' 

但即使在这里我也遇到了一些问题,因为我必须为新行添加/n/n 。但是,一旦我将 c3 更改为 c2.replace('}\n\ndata:{', ', '),我就会得到 Process finish 并退出代码137(被信号 9 中断:SIGKILL)。来自.NET,我可以使用反序列化器轻松处理这个问题,我想知道是否有类似的方法来反序列化数据。 我通过 sseclient 获取数据,并且能够将它们存储为字节而不是字符串,如果这有帮助,仅供引用。

有什么建议吗?

最佳答案

玩弄替换当然是一条复杂的道路 - 该语言确实具有用于这种内置转义的解析器 - 其中更简单的方法是通过 eval 调用传递包含 JSON 的字符串。但是 eval 很少需要,并且在大多数情况下应该避免,因为“不优雅” - 即使不是完全不安全(但不安全实际上只适用于您无法控制输入数据 - 甚至它们, ast.literal_eval 而不是普通的 eval 可以缓解那)。无论如何,格式还存在其他问题,会阻止 eval 完全工作 - 例如,最外面的 data: 缺少引号。

随机咆哮,如果您的文件内容实际上是:

data:{\"data\":[\"Kendrick\",\"Lamar\"]}\n\ndata:{\"data\":[\"David\",\"Bowie\"]}\n\n

它有两个问题:最外面的 data 的“引用不足”和 内部数据的“过度扩展”。

在交互式 Python session 中,使用“原始字符串”标记,我可以输入示例行,因为它将从文件中读取:

In [263]: a = r"""data:{\"data\":[\"Kendrick\",\"Lamar\"]}\n\ndata:{\"data\":[\"David\",\"Bowie\"]}\n\n"""                                             

In [264]: print(a)                                                                                                                                     
data:{\"data\":[\"Kendrick\",\"Lamar\"]}\n\ndata:{\"data\":[\"David\",\"Bowie\"]}\n\n

因此,要删除一级反斜杠 - Python 有“unicode_escape”文本编码,但它仅适用于字节对象。然后我们求助于“latin1”编码,因为它提供了“a”中的 unicode 文字到字节的逐字节转换,然后应用 unicode_escape 删除“\”:

In [266]: b = a.encode("latin1").decode("unicode_escape")  

In [267]: print(b, "\n", repr(b))                                                                                                                      
data:{"data":["Kendrick","Lamar"]}

data:{"data":["David","Bowie"]}


 'data:{"data":["Kendrick","Lamar"]}\n\ndata:{"data":["David","Bowie"]}\n\n'

现在很容易解析: 我们在“\n\n”处分割结果字符串,并得到一个包含一条记录的列表 (您称之为“数据集”的数据集)每个元素。然后我们诉诸字符串 操作以摆脱起始的 "data:",最后,json.load 可以处理剩余的部分。

所以:

import json

raw_data = open("mystrangefile.pseudo_json").read()
data = data.encode("latin1").decode("unicode_escape")
records = [json.loads(record.split(":", 1)[-1]) for record in data.split("\n\n")]

“记录”现在应该包含行为良好的 Python 对象字典,您可以将其放入数据库中。 (除非 Pandas 可以提供列到数据库的自动映射,否则这似乎是一个不必要的步骤 - 具有适当的开放数据库连接的原始 connection.executemany(""" INSERT ...""", records) 就足够了。

此外,在旁注中,您提到您可以使用 .NET 反序列化器轻松处理此问题:前提是您的文件不像您向我们展示的那样损坏 - 没有可能的标准序列化器知道如何处理此类特定的开箱即用的数据格式。但是,如果您实际上更精通另一种语言/技术来做到这一点,您可以只编写一个从损坏的输入到正确编码的文件的转换器,并将其用作中间步骤。

关于python - 如何反序列化分割后的json数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56583979/

相关文章:

json - gson flat json 到嵌套对象需要序列化器/反序列化器吗?

c - 结构体元素的值在返回之前设置,但不在返回时设置

c# - System.Text.Json - 将嵌套对象反序列化为字符串

python - 如何替换字符串中的 `\n` 而不是 Python 中的 `\n\n`?

python - 模拟具有特定返回值的实例方法?

c# - 将 JSON 数据发布到 ASP.NET MVC

json - JacksonPolymorphicDeserialization : JsonMappingException

python - 对多个 NumPy 数组进行逻辑或运算

python - 使用 beautifulsoup 从标签 <a> 获取字符串

android - 在android中通过http post方法发送json对象