[Python] Ошибка при загрузке JSON

mbngj

Итак, начался мой путь с Питоном и первой задачей является загрузить JSON файла.
Почитав документацию пытался просто загружать:
import json   
f = open('testset','r')
data = json.load(f)

От чего получал ошибку
Traceback (most recent call last):
File "/Users/--/PycharmProjects/First/main.py", line 7, in <module>
data = json.load(f)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/json/__init__.py", line 271, in load
return loads(fp.read
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 00 in position 537: ordinal not in range(128)

Решив, что проблема с кодировками достаточно распространенная и наверняка ответ на мой вопрос где-нибудь да есть - облазил все и вся, даже находил решения, которые помогали кому-то, но со мной все безуспешно...
После изучения вопроса код был немного изменен и получено следующее:
# -*- coding: utf-8 -*-
import json
f = open('testset','r',encoding='utf-8')
data = json.load(f)

Компиляция которого выдавала ошибку
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/json/decoder.py", line 368, in raw_decode
obj, end = self.scan_once(s, idx)
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/--/PycharmProjects/First/main.py", line 6, in <module>
data = json.load(f)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/json/__init__.py", line 274, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/json/__init__.py", line 319, in loads
return _default_decoder.decode(s)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/json/decoder.py", line 352, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/json/decoder.py", line 370, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

Так же для интереса была получена строка в позициях 527-547:
print (open('testset','rb').read[527:547])

b'"categs":"\0\x94\0\xb5\0\xba\0\xbe\1\x80'

Что указывает на проблему с русским языком (насколько я понял из прочитанных материалов добавив codecs, получил нормальную строку:
print (codecs.open('testset','rb', "utf-8").read[527:547])

"categs":"Декоративн

В случае использования подхода с codecs
# -*- coding: utf-8 -*-
import codecs
import json
f = codecs.open('testset','rb', "utf-8")
data = json.load(f)

Получаем ту же ошибку, что и с параметром encoding= в open
ValueError: No JSON object could be decoded

Уже около недели мучаюсь с этим и не могу приступить к следующему этапу работы, потому что тупо не могу открыть файл :mad:
Пробовал на Mac OS X 10.7.4 и на Windows 7, ошибки немного отличаются, но файл все равно не грузится. Версия Питона - 3.3. Пробовал так же и на 2.7 - там тоже не грузится, но еще и описание ошибок более скудное.
От безысходности прошу помощи от понимающих особенности JSON, Python и кодировок :crazy:

Bird_V

Дык и правильно Python ругается - не JSON у тебя на входе.

kedr1983

Если с англоязычными данными проблем нет, поставь encoding внутри load.
 
 data = json.load(f, encoding='utf-8') 

#-*- coding... нужен только для того, чтобы указать кодировку файла с твоим кодом.

mbngj

Если с англоязычными данными проблем нет, поставь encoding внутри load.
Ставил и там, эффекта никакого - UnicodeDecodeError: 'ascii' codec can't decode byte 00 in position 537: ordinal not in range(128)
Пробовал еще с cp1251, падает уже на элементе 40000+, но даже убирая его из файла все равно дальше не движется :(
Дык и правильно Python ругается - не JSON у тебя на входе.
Напишу тем, кто мне дал этот файл про кодировку, может там что интересное и что похоже у меня неправильный JSON. Надеюсь не буду выглядеть дураком :crazy:

kedr1983

Попробуй еще вариант: прочитай файл в строковую переменную (чтение, похоже, у тебя проходит успешно) и переведи через json.loads.

Bird_V

Скажем так: в этом файле есть куски JSON. Например это - не JSON:

bnr 100001887 {"experiments":"{\"filter_by_own\":{\"camp\":0}}"}

А вот это - JSON:

{"experiments":"{\"filter_by_own\":{\"camp\":0}}"}

mbngj

Попробуй еще вариант: прочитай файл в строковую переменную (чтение, похоже, у тебя проходит успешно) и переведи через json.loads.
Та же ошибка - что мол не JSON.
Скажем так: в этом файле есть куски JSON. Например это - не JSON:
code:
bnr 100001887 {"experiments":"{\"filter_by_own\":{\"camp\":0}}"}
А вот это - JSON:
code:
{"experiments":"{\"filter_by_own\":{\"camp\":0}}"}
Видимо да.
Не рассматривал такой вариант, потому что сам вроде бы ничего еще не понимаю в этом, а файл получил от людей, которые сами их используют. Но, видимо что-то не так они сделали все таки.
Спасибо за внесенную определенность в текущее состояние дел!

kedr1983

Добрался до компа, посмотрел файлик.
верно отметил. Это не json, а многострочный файл.
В принципе можно работать и с этим.
>>> import json
>>> f = open('testset','r')
>>> l = f.readline # читаем первую строку
>>> s=l.split('\t')[-1][:-1] # Разрезаем знаком табуляции, берем последний элемент получившегося списка, исключаем '\n'
>>> s
'{"experiments":"{\\"filter_by_own\\":{\\"camp\\":0}}"}'
>>> # С лишним "эскейпом", ну да ладно, процессу не помешает
... data = json.loads(s)
>>> data
{u'experiments': u'{"filter_by_own":{"camp":0}}'}
Но подозреваю, что это не совсем то, что должны были прислать (они это как JSON позиционировали?). Один из двух типов данных на строку (bnr и phr — что есть что, вам виднее) с разным количеством аргументов, разделенных табуляцией. JSON-объект в них стоит последним.
С кодировкой там всё нормально. Манипуляций с декодингом не требуется.

>>> l = f.readline # Вторая строка
>>> s = l.split('\t')[-1][:-1]
>>> s
{"src_simpgraphs":{"bm":{"total_uncut":1011,"smpg_uncut":{"Slotstat":17,"HitLog":389,"Bindings":1243,"Models":0,"BannerText":0,"Banners":595,"QueryLogQQ":3,"Tags":0,"BannerUrl":0,"QueryLog":397}},"own":{"total_uncut":287,"smpg_uncut":{"Slotstat":13,"HitLog":23,"Bindings":97,"Models":0,"BannerText":1,"Banners":213,"QueryLogQQ":13,"Tags":0,"BannerUrl":1,"QueryLog":80}}},"experiments":"{}","match_type":"normal","bmid":"1368580042-bmlink03g","categs":"\0\x94\0\xb5\0\xba\0\xbe\1\x80\0\xb0\1\x82\0\xb8\0\xb2\0\xbd\0\xb0\1\x8f \0\xba\0\xbe\1\x81\0\xbc\0\xb5\1\x82\0\xb8\0\xba\0\xb0 \0\xb4\0\xbb\1\x8f \0\xb3\0\xbb\0\xb0\0\xb7"}
>>> # А тут без лишнего "эскейпа" о_О
... data = json.loads(s)
>>> data
{u'experiments': u'{}', u'bmid': u'1368580042-bmlink03g', u'src_simpgraphs': {u'bm': {u'total_uncut': 1011, u'smpg_uncut': {u'QueryLog': 397, u'Tags': 0, u'Models': 0, u'BannerUrl': 0, u'HitLog': 389, u'QueryLogQQ': 3, u'Slotstat': 17, u'BannerText': 0, u'Banners': 595, u'Bindings': 1243}}, u'own': {u'total_uncut': 287, u'smpg_uncut': {u'QueryLog': 80, u'Tags': 0, u'Models': 0, u'BannerUrl': 1, u'HitLog': 23, u'QueryLogQQ': 13, u'Slotstat': 13, u'BannerText': 1, u'Banners': 213, u'Bindings': 97}}}, u'match_type': u'normal', u'categs': u'\u0414\u0435\u043a\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u043a\u043e\u0441\u043c\u0435\u0442\u0438\u043a\u0430 \u0434\u043b\u044f \u0433\u043b\u0430\u0437'}
>>> print data.values[-1]
Декоративная косметика для глаз
>>> f.close
Оставить комментарий
Имя или ник:
Комментарий: