JSON.loads()Python中的ValueError额外数据

Pyt*_*00b 1 python url json urllib2

我正在尝试从JSON提要中读取单个值.以下是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
}
Run Code Online (Sandbox Code Playgroud)

我不能分享实际的URL,但如果我运行,上面是大约150个结果中的前2个

print results
Run Code Online (Sandbox Code Playgroud)

之前

json.loads()
Run Code Online (Sandbox Code Playgroud)

线.

我的代码:

import urllib2
import json

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

for row in jsondata:
     print row['sendtoken']
     print row['recipient_domain']
Run Code Online (Sandbox Code Playgroud)

我想输出像

token1
hotmail.com
Run Code Online (Sandbox Code Playgroud)

每个条目.

我收到这个错误:

ValueError: Extra data: line 2 column 1 - line 133 column 1 (char 583 - 77680)
Run Code Online (Sandbox Code Playgroud)

我离Python专家很远,这是我第一次使用JSON.我花了很多时间在谷歌和Stack Overflow上,但我找不到适用于我的特定数据格式的解决方案.

aba*_*ert 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()
Run Code Online (Sandbox Code Playgroud)

但是,流中的第二个JSON对象也存在错误.看看这部分:

…
"message": "internal error,
"id": "mailerX",
…
Run Code Online (Sandbox Code Playgroud)

有一个失踪""internal error.如果你解决了这个问题,那么上面的函数将迭代两个JSON对象.

希望这个错误是由于您尝试通过重写来手动"复制和粘贴"数据而导致的.如果它在您的原始源数据中,那么您会遇到更大的问题; 你可能需要从头开始编写一个"破JSON"解析器,它可以启发式地猜测数据的目的是什么.或者,当然,让任何正在生成源的人正确地生成它.


*通常,使用第二个参数raw_decode传递起始索引更有效,而不是每次都切掉剩余部分的副本.但raw_decode无法处理领先的空白.切片和剥离比编写从给定索引跳过空白的代码要容易一些,但如果这些副本的内存和性能成本很重要,则应编写更复杂的代码.