Дамп в JSON добавляет дополнительные двойные кавычки и экранирование кавычек

86

Я получаю данные Twitter с помощью инструмента Python и выгружаю их в формате JSON на свой диск. Я заметил непреднамеренное экранирование всей строки данных для твита, заключенного в двойные кавычки. Кроме того, все двойные кавычки фактического форматирования JSON экранируются обратной косой чертой.

Они выглядят так:

"{\" created_at \ ": \" Пт, 8 августа, 11:04:40 +0000 2014 \ ", \" id \ ": 497699913925292032,

Как мне этого избежать? Должен быть:

{"created_at": "Пт, 8 августа, 11:04:40 +0000 2014" .....

Мой код выхода из файла выглядит так:

with io.open('data'+self.timestamp+'.txt', 'a', encoding='utf-8') as f:
            f.write(unicode(json.dumps(data, ensure_ascii=False)))
            f.write(unicode('\n'))

Непреднамеренное экранирование вызывает проблемы при чтении файла JSON на более позднем этапе обработки.

слишком пчела
источник

Ответы:

140

Вы дважды кодируете свои строки JSON. dataэто уже строка JSON, и не нужно быть закодированы снова :

>>> import json
>>> not_encoded = {"created_at":"Fri Aug 08 11:04:40 +0000 2014"}
>>> encoded_data = json.dumps(not_encoded)
>>> print encoded_data
{"created_at": "Fri Aug 08 11:04:40 +0000 2014"}
>>> double_encode = json.dumps(encoded_data)
>>> print double_encode
"{\"created_at\": \"Fri Aug 08 11:04:40 +0000 2014\"}"

Просто напишите их прямо в свой файл:

with open('data{}.txt'.format(self.timestamp), 'a') as f:
    f.write(data + '\n')
Мартейн Питерс
источник
f.write (data + '\ n') - коррелирует с - data = encoded_data - из вашего примера.
Рич Элсвик
@RichElswick OP использует переменную data, которая содержит уже закодированные данные JSON, поэтому да, я использовал имя переменной, encoded_dataчтобы проиллюстрировать, что происходит.
Мартейн Питерс
9

Еще одна ситуация, когда это нежелательное экранирование может произойти, - это попытка использовать json.dump () для предварительно обработанного вывода json.dumps (). Например

import json, sys
json.dump({"foo": json.dumps([{"bar": 1}, {"baz": 2}])},sys.stdout)

приведет к

{"foo": "[{\"bar\": 1}, {\"baz\": 2}]"}

Чтобы этого избежать, вам нужно передавать словари, а не вывод json.dumps (), например

json.dump({"foo": [{"bar": 1}, {"baz": 2}]},sys.stdout)

который выводит желаемый

{"foo": [{"bar": 1}, {"baz": 2}]}

(Вы спросите, зачем вам предварительно обрабатывать внутренний список с помощью json.dumps ()? Ну, у меня была другая функция, которая создавала этот внутренний список из других вещей, и я подумал, что имеет смысл вернуть объект json из эта функция ... Неправильно.)

Майк Максвелл
источник