Как исправить возможно поврежденный json файл? Проблемы с фигурной скобкой "{" (Python3) - PullRequest
0 голосов
/ 27 января 2020

Это такая странная проблема, я даже не знаю, как спросить, но я попробую. У меня есть 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()

Дело в том, что код отлично работает на рукописном тестовом файле с той же структурой, но не с исходные файлы или меньшие тестовые файлы, полученные из оригиналов.

Я попытался выполнить простой поиск "}" и "{" отдельно в текстовом редакторе, что, как оказалось, нормально. Но если я попытаюсь найти "} {" или "} {", ничего не будет найдено. Хотя я вижу, что они явно там.

Последняя находка: я попытался открыть отредактированную версию моего небольшого тестового файла в Nano в Linux и переместился через проблемную область. По какой-то причине для перемещения по фигурной скобке "{" требуется два нажатия клавиши со стрелкой вправо. Так что там явно что-то странное. Как мне узнать что? Или какие-либо другие предложения, которые могут помочь?

Ответы [ 3 ]

0 голосов
/ 27 января 2020

Это один из подходов.

Пример:

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',.....
0 голосов
/ 27 января 2020

Вот еще одно решение, которое похоже на то, что вы пытались

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'}
0 голосов
/ 27 января 2020

Самое простое решение - просто создать массив 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...