【问题标题】:Creating a json output in python在python中创建一个json输出
【发布时间】:2017-05-09 09:57:05
【问题描述】:

我正在尝试以 json 形式返回函数的响应。输出是一个列表,每个元素都是一个字典。打印输出时我没有看到任何错误。当我遍历输出时出现问题。我一一得到输出中的所有字符。请参阅示例代码和示例输出以正确理解。

代码:

import requests
import json
import sys
from bs4 import BeautifulSoup
from collections import OrderedDict

class Cricbuzz():
    url = "http://synd.cricbuzz.com/j2me/1.0/livematches.xml"
    def __init__(self):
        pass

    def getxml(self,url):
        try:
            r = requests.get(url)
        except requests.exceptions.RequestException as e: 
            print e
            sys.exit(1)
        soup = BeautifulSoup(r.text,"html.parser")
        return soup

    def matchinfo(self,match):
        d = OrderedDict()
        d['id'] = match['id']
        d['srs'] = match['srs']
        d['mchdesc'] = match['mchdesc']
        d['mnum'] = match['mnum']
        d['type'] = match['type']
        d['mchstate'] = match.state['mchstate']
        d['status'] = match.state['status']
        return d

    def matches(self):
        xml = self.getxml(self.url)
        matches = xml.find_all('match')
        info = []
        for match in matches:
            info.append(self.matchinfo(match))
        data = json.dumps(info)
        return data 
c = Cricbuzz()
matches = c.matches()
print matches #print matches -  output1
for match in matches:
    print match #print match -  output2

“打印匹配”,即上面代码中的 output1 给了我以下输出:

[
    {
        "status": "Coming up on Dec 24 at 01:10 GMT", 
        "mchstate": "nextlive", 
        "mchdesc": "AKL vs WEL", 
        "srs": "McDonalds Super Smash, 2016-17", 
        "mnum": "18TH MATCH", 
        "type": "ODI", 
        "id": "0"
    }, 
    {
        "status": "Ind U19 won by 34 runs", 
        "mchstate": "Result", 
        "mchdesc": "INDU19 vs SLU19", 
        "srs": "Under 19 Asia Cup, 2016", 
        "mnum": "Final", 
        "type": "ODI", 
        "id": "17727"
    }, 
    {
        "status": "PRS won by 48 runs", 
        "mchstate": "Result", 
        "mchdesc": "PRS vs ADS", 
        "srs": "Big Bash League, 2016-17", 
        "mnum": "5th Match", 
        "type": "T20", 
        "id": "16729"
    }
]

但是“打印匹配”,即 for 循环内上述代码中的 output2 给出了以下输出:

[
    {
    "
    i
    d
    "
    :

    "
    0
    "
    ,

    "
    s
    r
    s
    "
    :

    "
    M
    c
    D
    o
    n
    a
    l
    d
    s

    S
    u
    p
    e
    r

    S
    m
    a
    s
    h
    ,

    2
    0
    1
    6
    -
    1
    7
    "
    ,

    "
    m
    c
    h
    d
    e
    s

如您所见,匹配的每一行都会打印一个字符。我想在打印匹配时获取字典对象。

【问题讨论】:

  • 您不能,因为您将 Python 对象序列化为 JSON,这是一种基于字符串的编码。您要么必须反序列化 match 返回的内容,要么不使用 json.dumps
  • 您序列化了返回数据,这意味着您迭代了序列化的字符串,而不是预序列化的对象。 JSON 是一种序列化数据格式,可用于保存到文件或传递给其他程序,但对于在程序中处理几乎没有用处。只需将 python 对象传回......你不需要将它们 jsonize。
  • 在 json 中序列化也会破坏 OrderedDict 列表的排序。字典在 json 中本质上是 _un_ordered。

标签: python json beautifulsoup


【解决方案1】:

如果您在返回data 之前像在info 上一样调用json.dumps,则该值将转换为json 字符串。如果你想迭代 json 字符串 表示的可迭代对象,你必须从 json 中加载数据。

考虑:

import json

info = [ { "a": 1}, { "b": 2} ]
data = json.dumps(info,indent=2)
print data
for i in data:
    print i
for i in json.loads(data):
    print i


$ python t.py
[
  {
    "a": 1
  },
  {
    "b": 2
  }
]
[




{






"
a
"
:

1




}
,





{








"
b
"
:

2




}


]
{u'a': 1}
{u'b': 2}

【讨论】:

    【解决方案2】:
        def matches(self):
            xml = self.getxml(self.url)
            matches = xml.find_all('match')
            info = []
            for match in matches:
                info.append(self.matchinfo(match))
            data = json.dumps(info) # This is a string
            return data             # This is a string
    
    c = Cricbuzz()
    matches = c.matches()           # This is a string
    print matches 
    for match in matches:           # Looping over all characters of a string
        print match 
    

    我想你只需要return info,这是一个列表。稍后当您确实需要 JSON 时,您可以在该函数之外 json.dumps()

    或者,如果您确实希望该函数返回一个 JSON 字符串,那么您必须将其解析回一个列表。

    for match in json.loads(matches): 
    

    【讨论】:

    • 如果我只返回信息,我会得到以下输出 - pastebin.com/yAg2QFyn。 “OrdereDict”甚至出现在输出中。
    • 当然...您正在打印整个对象。或OrderedDictrepr()
    • 也就是说没有错,不知道你还期待什么
    【解决方案3】:

    Json.dumps 返回一个字符串。

    如果您希望在迭代过程中获得列表中的每个 dict,您可以将您的响应包装成:

    matches = json.loads(matches)
    

    顺便说一句,很高兴将它以前作为简单的 JSON 验证转储,因为它使有效的 JSON 从无效:首先用双引号替换单引号等。这就是为什么我建议不要跳过 json.dumps你正在尝试做。

    【讨论】:

      【解决方案4】:

      matches 是 JSON 字符串,而不是字典,因此 for match in matches: 会遍历字符串中的字符。

      如果你想要字典,函数应该返回info而不是json.dumps(info)。或者你可以这样做:

      for match in json.loads(matches):
      

      将 JSON 解析回字典。

      通常,您应该在程序中以结构化类型(如字典和列表)的形式移动数据,并且仅在通过网络发送或存储到文件时将它们转换为 JSON。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-10
        • 1970-01-01
        • 1970-01-01
        • 2023-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多