【问题标题】:Python ijson - parse error: trailing garbage // bz2.decompress()Python ijson - 解析错误:尾随垃圾 // bz2.decompress()
【发布时间】:2021-12-04 17:42:54
【问题描述】:

我在用 ijson 解析 json 时遇到了一个错误。

背景: 我有一系列(大约 1000 个)推特数据大文件,这些文件以“.bz2”格式压缩。我需要将文件中的元素放入pd.DataFrame 以进行进一步分析。我已经确定了我需要获取的密钥。我很谨慎地将推特数据放上去。

尝试: 我已设法使用bz2.decompress 使用以下代码解压缩文件:

## Code in loop specific for decompressing and parsing - 

with open(file, 'rb') as source:
                # Decompress the file
                json_r = bz2.decompress(source.read())
                json_decom =  json_r.decode('utf-8') # decompresses one file at a time rather than a stream
                
                # Parse the JSON with ijson 
                parser = ijson.parse(json_decom)
                for prefix, event, value in parser:
                    # Print selected items as part of testing
                    if prefix=="created_at":
                        print(value)
                    if prefix=="text":
                        print(value)
                    if prefix=="user.id_str":
                        print(value)

这会产生以下错误:

IncompleteJSONError: parse error: trailing garbage
          estamp_ms":"1609466366680"}  {"created_at":"Fri Jan 01 01:59
                     (right here) ------^

两件事:

  • 我的解压方法是否正确并为 ijson 解析提供了正确的文件类型(ijson 需要字节和 str)?
  • 是 JSON 错误吗? // 如果是 JSON 错误,是否可以开发某种错误处理程序来移动到下一个文件 - 如果可以,任何建议都将不胜感激?

任何帮助将不胜感激。

谢谢你,詹姆斯

【问题讨论】:

    标签: python twitter error-handling bz2 ijson


    【解决方案1】:

    直接回答你的两个问题:

    • 解压方法是正确的,因为它会生成 JSON 数据,然后将其提供给 ijson。正如您所指出的,ijson 可与 str 和 bytes 输入一起使用(尽管后者是首选);如果你给 ijson 一些非 JSON 输入,你不会看到显示 JSON 数据的错误。

    • 这是一个非常常见的错误,描述为in ijson's FAQ。这基本上意味着您的 JSON 文档具有多个顶级值,这不是标准 JSON,但 ijson 通过使用 multiple_values 选项支持(有关详细信息,请参阅文档)。

    关于整个代码:虽然它工作正常,但可以改进:使用ijson 的全部意义在于您可以避免将完整的 JSON 内容加载到内存中。您发布的代码并没有利用它的优势:它首先打开 bz 压缩文件,将其作为一个整体读取,将 that 作为一个整体解压缩,(不必要地)解码 that 作为一个整体,然后将解码后的数据作为输入提供给ijson。如果你的输入文件很小,解压后的数据也很小,你不会看到任何影响,但如果你的文件很大,那么你肯定会开始注意到它。

    更好的方法是通过所有操作流式传输数据,以便一切都以增量方式发生:解压缩、不解码和 JSON 解析。大致如下:

    with bz2.BZ2File(filename, mode='r') as f:
        for prefix, event, value in ijson.parse(f):
            # ...
    

    作为蛋糕上的樱桃,如果您想从中构建一个 DataFrame,您可以使用 DataFrame 的data argument 直接使用上述结果构建 DataFrame。 data 可以是可迭代的,因此您可以例如在生成器上方制作代码并将其用作data。再次,类似于:

    def json_input():
       with bz2.BZ2File(filename, mode='r') as f:
           for prefix, event, value in ijson.parse(f):
               # yield your results
    
    df = pandas.DataFrame(data=json_input())
    

    【讨论】:

      猜你喜欢
      • 2020-04-08
      • 2022-01-15
      • 2016-12-15
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 2016-03-25
      相关资源
      最近更新 更多