2014-10-29 68 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,但以上是大约150的结果显示,如果我之前运行

print results 

第一2

json.loads() 

line。

我的代码:

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无效 – 2014-10-29 00:16:25

回答

8

问题是您的数据不会形成JSON对象,因此您无法使用json.loads对它们进行解码。


首先,这似乎是由空格隔开JSON对象的一个​​序列。既然你不会告诉我们有关数据来自何处的任何信息,这实际上只是一个受过教育的猜测;希望任何文档或同事或任何告诉你有关此URL的内容告诉你实际的格式。但让我们假设我的教育猜测是正确的。

在Python中解析JSON对象流的最简单方法是使用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]