如何从JSON表中提取字典

时间:2015-10-19 09:16:25

标签: python json dictionary robotframework

我正在使用机器人框架和请求库测试REst API API的JSON响应采用表格的形式。 我正在使用机器人框架来测试这个API,我想将这个表拆分成字典,以便我可以使用robot framework关键字来测试响应。

以下是我的JSON响应示例:

[
  {
      locale: "fr_FR",
      day: "2015-12-01",
      displayPricePerPerson: 9800,
      displayTotalPrice: 9800,
      promotion: false,
      minLos: 1
},
{
      locale: "fr_FR",
      day: "2015-12-02",
      displayPricePerPerson: 9800,
      displayTotalPrice: 9800,
      promotion: false,
      minLos: 1
 },
[

理想情况下,我想以字典的形式提取整个响应,以便我可以遍历响应并断言键和值。

所以我不会将字典嵌入到表中,而只会使用字典:

{
      locale: "fr_FR",
      day: "2015-12-01",
      displayPricePerPerson: 9800,
      displayTotalPrice: 9800,
      promotion: false,
      minLos: 1
},
{
      locale: "fr_FR",
      day: "2015-12-02",
      displayPricePerPerson: 9800,
      displayTotalPrice: 9800,
      promotion: false,
      minLos: 1
 },

我尝试过收藏和请求库但是我收到了错误:

${JSON}=  To JSON  ${resp.content}
${DICT}=  Convert To List  ${JSON}
 Log  ${DICT}
:FOR  ${KEY}  IN  locale  day  displayPricePerPerson  displayTotalPrice  promotion  minLos
          \   Run Keyword And Continue On Failure  List Should Contain Value  ${JSON}  ${KEY}

Error : ValueError: dictionary update sequence element #0 has length 6; 2 is required

2 个答案:

答案 0 :(得分:1)

                you have dictionaries in your list already. though badly formed.they are missing quotes around the keys

                    lt = [
                      {
                          "locale": "fr_FR",
                          "day": "2015-12-01",
                          "displayPricePerPerson": 9800,
                          "displayTotalPrice": 9800,
                          "promotion": False,
                          "minLos": 1
                    },
                    {
                          "locale": "fr_FR",
                          "day": "2015-12-02",
                          "displayPricePerPerson": 9800,
                          "displayTotalPrice": 9800,
                          "promotion": False,
                          "minLos": 1
                     },
                    ]

                    for el in lt:
                        print(type(el))

                    <class 'dict'>
                    <class 'dict'>

                    d1 = lt[0]
                    d2 =lt[1]

                    print(d1.items())
                    dict_items([('day', '2015-12-01'), ('locale', 'fr_FR'), ('displayPricePerPerson', 9800), ('minLos', 1), ('promotion', False), ('displayTotalPrice', 9800)])

                    print(d2.items())
                    dict_items([('day', '2015-12-02'), ('locale', 'fr_FR'), ('displayPricePerPerson', 9800), ('minLos', 1), ('promotion', False), ('displayTotalPrice', 9800)])

                to convert to list of dicts this:
lt2 = '''[
    {
        locale: "fr_FR",
        day: "2015-12-01",
        displayPricePerPerson: 9800,
        displayTotalPrice: 9800,
        promotion: false,
        minLos: 1
    },
    {
        locale: "fr_FR",
        day: "2015-12-02",
        displayPricePerPerson: 9800,
        displayTotalPrice: 9800,
        promotion: false,
        minLos: 1
    },
]
'''

    def convert_ECMA_Javascript(st):
        # convert badly formed strings to json format
        import json

        result = re.sub(r'(\w+):',r'"\1":',st)
        result= re.sub(r'false',r'"False"',result)
        result= re.sub(r'true',r'"True"',result)
        result= re.sub(r'\[|\]',r'',result)
        result= re.sub(r'\b(\d+)\b(?!"|-)',r'"\1"',result)
        result= re.sub(r'\n|\t',r'',result)
        li = re.findall(r'{.*?}', result)

        result = []
        for s in li:
            result.append(json.loads(s))

        return result

    pp(convert_ECMA_Javascript(lt2))

    [{'day': '2015-12-01',
      'displayPricePerPerson': '9800',
      'displayTotalPrice': '9800',
      'locale': 'fr_FR',
      'minLos': '1',
      'promotion': 'False'},
     {'day': '2015-12-02',
      'displayPricePerPerson': '9800',
      'displayTotalPrice': '9800',
      'locale': 'fr_FR',
      'minLos': '1',
      'promotion': 'False'}]

    for el in convert_ECMA_Javascript(lt2):
        for k,v in el.items():
            print(k,":", v)

    day : 2015-12-01
    displayPricePerPerson : 9800
    minLos : 1
    promotion : False
    displayTotalPrice : 9800
    locale : fr_FR
    day : 2015-12-02
    displayPricePerPerson : 9800
    minLos : 1
    promotion : False
    displayTotalPrice : 9800
    locale : fr_FR

答案 1 :(得分:1)

假设实际数据是有效的JSON(问题中的数据不是),一旦调用To JSON,返回的数据就是可以迭代的字典列表。您应该能够在没有任何进一步转换的情况下循环它们。

例如:

${JSON}=    To JSON    ${resp.content}
:FOR    ${item}    IN    @{JSON}
    \  log    locale: ${item["locale"]}

以上内容将为JSON数据中的每个字典记录一行。