我试图从JSON Feed中读取单个值。以下是Feed数据的示例:
{
"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
}
我无法分享实际的网址,但以上是我运行时显示的大约150个结果中的前2个
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 :(得分: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
无法处理前导空格。切片和剥离比编写从给定索引跳过空白的代码要容易一些,但如果这些副本的内存和性能成本很重要,则应编写更复杂的代码。 < / p>
答案 1 :(得分:1)
那是因为json.loads(和json.load)不解码多个json对象。 例如,您想要的json文件可能是: [“a”:1,“b”:2] 但是代码的结构文件确切地说是: [“a”:1,“b”:2] [“a”:1,“b”:2]