【问题标题】:How to fix a possibly corrupted json file? Problems with a curly bracket character "{" (Python3)如何修复可能损坏的 json 文件?花括号字符“{”的问题(Python3)
【发布时间】:2020-01-27 08:41:25
【问题描述】:

这是一个奇怪的问题,我什至不知道如何问,但我会尝试。我有一些 json 文件,其中包含网络抓取数据,每个文件有多个条目,它们看起来像这样:

{
"doc_id": "some_number",
"url": "www.seedurl1.com",
"scrape_date": "2019-10-22 16:17:22",
"publish_date": "unknown",
"author": "unknown",
"urls_out": [
"https://www.something.com",
"https://www.sometingelse.com/smth"
],
"text": "lots of text here"
}
{
"doc_id": "some_other_number",
"url": "www.seedurl2.com/smth",
"scrape_date": "2019-10-22 17:44:40",
"publish_date": "unknown",
"author": "unknown",
"urls_out": [
"www.anotherurl.com/smth",
"http://urlx.com/smth.htm"
],
"text": "lots more text over here."
}

我试图格式化它们,以便每个条目都在自己的行上,如下所示:

{"doc_id": blah blah....} 
{"doc_id": blah blah blah...}

所以我这样做了:

    # Read the file
    f = codecs.open(file, 'r', encoding='utf-8-sig', errors='replace')
    text = f.read()
    f.close()

    # Check if }{ was found; 
    # this prints nothing for original files but finds everything in a hand written file
    pattern = '}{'
    print('Before editing: ', (re.findall(pattern, text)))

    # Getting rid of excess newlines and whitespaces
    newtext = " ".join(text.split())

    # Check if } { was found;
    # this prints nothing for original files but finds everything in a hand written file
    pattern = '} {'
    print('After editing: ', (re.findall(pattern, newtext)))

    # Put newlines in the right places
    finaltext = re.sub('} {', '}\n{', newtext)

    # Write the new JSON
    newfile = file[:-5]+'_ED.json'
    nf = codecs.open(newfile, 'w', encoding='utf-8', errors='replace')
    nf.write(finaltext)
    nf.close()

问题是,代码在具有相同结构的手写测试文件上完美运行,但不适用于原始文件或源自原始文件的较小测试文件。

我尝试在文本编辑器中分别简单地搜索“}”和“{”,结果没问题。但是,如果我尝试搜索“}{”或“} {”,则什么也找不到。虽然我可以看到他们清楚地在那里。

最后一个发现:我试图在 Linux 的 Nano 中打开我的小测试文件的编辑版本,然后移到了问题区域。出于某种原因,需要按两次右箭头键才能移过“{”大括号。所以那里显然有一些奇怪的东西。我怎样才能知道什么?或任何其他可能有帮助的建议?

【问题讨论】:

  • 您可以尝试直接从数据中复制粘贴模式,而不是给出 { 或 }?有时会隐藏一些非 utf-8 字符。
  • 你为什么不使用python的json库?这样操作调试方便很多。
  • @Saharsh 因为文件不是有效的 JSON?
  • 这有帮助吗? pypi.org/project/json-lines
  • @cricket_007 我的错。不知道初始文件可以具有 OP 定义的语法。

标签: json python-3.x curly-braces


【解决方案1】:

最简单的解决方案就是创建一个 JSON 数组以...

否则,我建议不要替换任何内容,只需计算匹配的括号即可。

count = 0
objects = 0
with open('file.txt') as f:
    for i, c in enumerate(f.read()):
      if c == '\n':
        continue
      elif c == '{':
        if i > 0 and count == 0:
          print()  # start new line before printing bracket
        count += 1
      elif c == '}':
        count -= 1
        if count == 0:  # found a complete JSON object
          objects += 1

      print(c, end='')
    print(f'\n\nfound {objects} objects')  # for debugging 

对于给定的文本,我最终得到了这个

{"doc_id": "some_number","url": "www.seedurl1.com","scrape_date": "2019-10-22 16:17:22","publish_date": "unknown","author": "unknown","urls_out": ["https://www.something.com","https://www.sometingelse.com/smth"],"text": "lots of text here"}
{"doc_id": "some_other_number","url": "www.seedurl2.com/smth","scrape_date": "2019-10-22 17:44:40","publish_date": "unknown","author": "unknown","urls_out": ["www.anotherurl.com/smth","http://urlx.com/smth.htm"],"text": "lots more text over here."}

found 2 objects

【讨论】:

  • 这实际上对有问题的文件也有效!非常感谢!
  • 我选择了这个作为接受的答案,因为它在我发现我的文件有什么问题之前就起作用了。在我发现我的问题后,@Saharsh 的答案也有效并且更简单(在我看来)。
【解决方案2】:

这是一种方法。

例如:

import json

with open(filename) as infile:
    data = json.loads("[" + infile.read().replace("}\n{", "},\n{") + "]")
    for i in data:
        print(i)

输出:

{'doc_id': 'some_number', 'url': 'www.seedurl1.com',.....
{'doc_id': 'some_other_number', 'url': 'www.seedurl2.com/smth',.....

【讨论】:

    【解决方案3】:

    这是另一种解决方案,与您尝试的方法有点接近

    import json
    
    with open('test.txt') as f:
        file = f.readlines()
    file = ['{'+i+'}'for i in "".join("".join(file).split("\n"))[1:-1].split("}{")]
    
    for i in file:
        print(json.loads(i))
    
    

    json 在这里仅用于验证单个 JSON。这给了

    {'doc_id': 'some_number', 'url': 'www.seedurl1.com', 'scrape_date': '2019-10-22 16:17:22', 'publish_date': 'unknown', 'author': 'unknown', 'urls_out': ['https://www.something.com', 'https://www.sometingelse.com/smth'], 'text': 'lots of text here'}
    {'doc_id': 'some_number', 'url': 'www.seedurl1.com', 'scrape_date': '2019-10-22 16:17:22', 'publish_date': 'unknown', 'author': 'unknown', 'urls_out': ['https://www.something.com', 'https://www.sometingelse.com/smth'], 'text': 'lots of text here'}
    

    【讨论】:

    • 糟糕。我认为需要处理空间,我们应该没问题。让我来做这件事。谢谢@cricket_007
    • 更新了答案。完全忘记在split() 中添加\n,这会删除所有空格。
    • 我试过这个,它被证明非常有用。起初它并没有在"}{" 处拆分,但在我打印出结果后,它告诉我在花括号之间隐藏了一个\ufeff,所以split("}\ufeff{") 解决了这个问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 2020-09-29
    • 2017-10-15
    • 2018-12-30
    • 2020-02-01
    • 1970-01-01
    相关资源
    最近更新 更多