2014-10-29 2 views
1

Я пытаюсь прочитать отдельные значения из канала JSON. Ниже приведен пример данных подачи:JSON.loads() Дополнительные данные ValueError в Python

{ 
    "sendtoken": "token1", 
    "bytes_transferred": 0, 
    "num_retries": 0, 
    "timestamp": 1414395374, 
    "queue_time": 975, 
    "message": "internalerror", 
    "id": "mailerX", 
    "m0": { 
     "binding_group": "domain.com", 
     "recipient_domain": "hotmail.com", 
     "recipient_local": "destination", 
     "sender_domain": "domain.com", 
     "binding": "mail.domain.com", 
     "message_id": "C1/34-54876-D36FA645", 
     "api_credential": "creds", 
     "sender_local": "localstring" 
    }, 
    "rejecting_ip": "145.5.5.5", 
    "type": "alpha", 
    "message_stage": 3 
} 
{ 
    "sendtoken": "token2", 
    "bytes_transferred": 0, 
    "num_retries": 0, 
    "timestamp": 1414397568, 
    "queue_time": 538, 
    "message": "internal error, 
    "id": "mailerX", 
    "m0": { 
     "binding_group": "domain.com", 
     "recipient_domain": "hotmail.com", 
     "recipient_local": "destination", 
     "sender_domain": "domain.com", 
     "binding": "mail.domain.com", 
     "message_id": "C1/34-54876-D36FA645", 
     "api_credential": "creds", 
     "sender_local": "localstring" 
    }, 
    "rejecting_ip": "145.5.5.5", 
    "type": "alpha", 
    "message_stage": 3 
} 

Я не могу разделить фактический URL, но выше, первые 2 из примерно 150 результатов, которые отображаются, если я бегу

print results 

перед тем

json.loads() 

линия.

Мой код:

import urllib2 
import json 

results = urllib2.urlopen(url).read() 
jsondata = json.loads(results) 

for row in jsondata: 
    print row['sendtoken'] 
    print row['recipient_domain'] 

Я хотел бы выход как

token1 
hotmail.com 

для каждой записи.

Я получаю эту ошибку:

ValueError: Extra data: line 2 column 1 - line 133 column 1 (char 583 - 77680) 

Я далек от эксперта Python, и это мой первый раз работает с JSON. Я потратил немало времени на поиск google и Stack Overflow, но я не могу найти решение, которое работает для моего конкретного формата данных.

+0

Ваш json недействителен –

ответ

8

Проблема в том, что ваши данные не образуют объект JSON, поэтому вы не можете декодировать их с помощью json.loads.


Во-первых, это появляется быть последовательность объектов JSON, разделенных пробелами. Поскольку вы не расскажете нам ничего о том, откуда взялись данные, это действительно просто просвещенная догадка; надеюсь, какая бы документация или коллега или что-то вам не говорила об этом URL-адресе, рассказала вам, какой формат на самом деле. Но давайте предположим, что мое образованное предположение верно.

Самый простой способ проанализировать поток объектов JSON в Python - использовать метод raw_decode. Что-то вроде этого: *

import json 

def parse_json_stream(stream): 
    decoder = json.JSONDecoder() 
    while stream: 
     obj, idx = decoder.raw_decode(stream) 
     yield obj 
     stream = stream[idx:].lstrip() 

Однако, есть также ошибка во втором объекте JSON в потоке. Посмотрите на эту часть:

… 
"message": "internal error, 
"id": "mailerX", 
… 

Там в отсутствие " после "internal error. Если вы исправите это, тогда функция выше будет перебирать два объекта JSON.

Надеюсь, эта ошибка была вызвана попыткой вручную «скопировать и вставить» данные, переписав его. Если он находится в исходных исходных данных, у вас есть гораздо более серьезная проблема; вам, вероятно, нужно написать «разбитый JSON» парсер с нуля, который может эвристически предполагать, какими должны были быть данные. Или, конечно, получить того, кто генерирует источник для его правильной генерации.


* В общем, это более эффективно использовать второй аргумент raw_decode пройти начальный индекс, а не отрезая копию остатка каждый раз.Но raw_decode не может обрабатывать ведущие пробелы. Немного проще просто нарезать и нарезать, чем писать код, который пропускает пробелы из данного индекса, но если важны затраты памяти и производительности этих копий, вы должны написать более сложный код.

0

Это потому, что json.loads (и json.load) не расшифровывает несколько объектов json. Например, json-файл, который вы хотите, может быть: ["a": 1, "b": 2] , но в точности файл структуры кода: ["a": 1, "b": 2 ] ["a": 1, "b": 2]

Смежные вопросы