【问题标题】:How to convert a JSON file into a dictionnary with Python 3如何使用 Python 3 将 JSON 文件转换为字典
【发布时间】:2017-10-23 17:29:26
【问题描述】:

第一篇文章在这里。 Python 和一般编程的新手。

基本上我正在关注这个人的tutorial(虽然不是查询相同的 API)关于从 Python 中的 JSON 响应中提取数据

这是我的(非常简单的)代码:

#!/usr/bin/env python
import json
import requests

url = 'http://calendar.voyages-sncf.com/cdp/api/proposals/v3/outward/FRPAR/FRGNL/2017-11-01/12-HAPPY_CARD/2/fr/fr?fareCodes=HC16&onlyDirectTrains=true'

json_data = requests.get(url).json()
json_segments = json_data['segments'] 

print (json_segments)

现在,不再提取 JSON 文件中标有“Segments”的数据。我收到此错误:

json_segments = json_data['status']
TypeError: list indices must be integers or slices, not str

所以,我尝试了 int(),使其成为整数但不起作用。

如果您能提供帮助,非常感谢。

【问题讨论】:

  • json_datalist,而不是 dict。例如,要从列表中获取第一项,请使用 json_data[0]
  • Json 格式并不意味着你会神奇地得到一本字典。你显然有一个清单。

标签: python json list


【解决方案1】:

requests.get().json() 返回的数据是一个数据列表。您可以使用for data in json_data: 循环遍历列表。然后您可以直接访问字典的“段”键。

#!/usr/bin/env python
import requests

url = 'http://calendar.voyages-sncf.com/cdp/api/proposals/v3/outward/FRPAR/FRGNL/2017-11-01/12-HAPPY_CARD/2/fr/fr?fareCodes=HC16&onlyDirectTrains=true'

json_data = requests.get(url).json()

for data in json_data:
    print(data['segments'])

关于教程代码的问题:

import urllib.parse

import requests

address = 'lhr'
main_api = 'http://maps.googleapis.com/maps/api/geocode/json?'
url = main_api + urllib.parse.urlencode({'address': address})
json_data = requests.get(url).json()
json_status = json_data['status']
print(json_status)

google geocoding api here(他在视频中使用的 api)的文档指定您将获得具有特定架构的字典。但是,当您从 http://calendar.voyages-sncf.com/cdp/api 获取数据时,它们不会返回相同的数据结构。在他们的情况下,它是一个字典列表。

因此,每次您从不同的 api(或同一 api 中的不同端点)获取新数据时,您将获得不同结构的数据。因此,您需要更改代码以处理每条数据。

JSON 只是在通过网络发送字符串后将字典、列表或其他本地(本地为 python、java 或您当时使用的任何语言)更改为字符串的标准方法。这可能会导致问题。特别是在 python 中,set() 不能直接更改为 JSON。它需要先更改为列表,然后更改为 JSON,然后再更改为列表,然后再更改为另一侧的集合。

以下示例是从 google 文档 here 复制而来,稍作修改使其更小且更具可读性。

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "1600",
               "short_name" : "1600",
               "types" : [ "street_number" ]
            },
         ],
         "formatted_address" : "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
         "geometry" : {
            "location" : {
               "lat" : 37.4224764,
               "lng" : -122.0842499
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 37.4238253802915,
                  "lng" : -122.0829009197085
               },
               "southwest" : {
                  "lat" : 37.4211274197085,
                  "lng" : -122.0855988802915
               }
            }
         },
         "place_id" : "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
         "types" : [ "street_address" ]
      }
   ],
   "status" : "OK"
}

【讨论】:

  • 哎呀。假设它只是一个列表。收回了我的回答。 :-)
  • 非常感谢,它有效。但是我不明白,在我观看的教程中,他如何直接获得字典。这是他的代码:main_api='maps.googleapis.com/maps/api/geocode/json?' url = main_api + urllib.parse.urlencode({'address': address}) json_data = requests.get(url).json() json_status = json_data['status'] 打印(json_status)
  • 你用的是python 3还是python 2?
  • 在我的回答中为您的问题添加了解释。
【解决方案2】:

欢迎来到 SO,很高兴你选择了 Python :)。

如果您是 Python 新手并打算使用表格,请不要犹豫,学习 pandas。有大量关于 pandas 的文档和问题。

例子:

import pandas as pd
url = 'http://calendar.voyages-sncf.com/cdp/api/proposals/v3/outward/FRPAR/FRGNL/2017-11-01/12-HAPPY_CARD/2/fr/fr?fareCodes=HC16&onlyDirectTrains=true'
df = pd.read_json(url)

from pandas.io.json import json_normalize
df = pd.concat(json_normalize(df["segments"].values[i]) for i in range(len(df)))

使用 pandas,您可以输出到列表、字典、csv、json 等...

这是一个返回 html 表的前 3 行的 sn-p:

print(df.head(3).to_html(index=False))

结果

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th>arrivalDate</th>
      <th>carrierCode</th>
      <th>departureDate</th>
      <th>destination.cityLabel</th>
      <th>destination.label</th>
      <th>destination.rrcode</th>
      <th>duration</th>
      <th>inventory</th>
      <th>onboardServices</th>
      <th>origin.cityLabel</th>
      <th>origin.label</th>
      <th>origin.rrcode</th>
      <th>physicalSpace</th>
      <th>quotations.12-HAPPY_CARD.cos</th>
      <th>quotations.12-HAPPY_CARD.cosLevel</th>
      <th>quotations.12-HAPPY_CARD.fareCode</th>
      <th>quotations.12-HAPPY_CARD.fareCondition.conditions</th>
      <th>quotations.12-HAPPY_CARD.fareCondition.fareName</th>
      <th>quotations.12-HAPPY_CARD.fareSequence</th>
      <th>quotations.12-HAPPY_CARD.fareSpecificRule</th>
      <th>quotations.12-HAPPY_CARD.passengerType</th>
      <th>trainNumber</th>
      <th>trainType</th>
      <th>transporter</th>
      <th>travelClass</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2017-11-01T19:46</td>
      <td>SN</td>
      <td>2017-11-01T16:41</td>
      <td>Grenoble</td>
      <td>Grenoble</td>
      <td>FRGNB</td>
      <td>185</td>
      <td>wdi</td>
      <td>[BAR, HAN, SMP]</td>
      <td>Paris</td>
      <td>Paris Gare de Lyon</td>
      <td>FRPLY</td>
      <td>B</td>
      <td>BN</td>
      <td>17</td>
      <td>HC16</td>
      <td>[Pièce d'identité à présenter à bord du train....</td>
      <td>TGVmax</td>
      <td>None</td>
      <td>None</td>
      <td>PT00AD</td>
      <td>6921</td>
      <td>TGD</td>
      <td>tgv</td>
      <td>2</td>
    </tr>
    <tr>
      <td>2017-11-01T17:45</td>
      <td>SN</td>
      <td>2017-11-01T14:41</td>
      <td>Grenoble</td>
      <td>Grenoble</td>
      <td>FRGNB</td>
      <td>184</td>
      <td>wdi</td>
      <td>[BAR, HAN, SMP]</td>
      <td>Paris</td>
      <td>Paris Gare de Lyon</td>
      <td>FRPLY</td>
      <td>B</td>
      <td>BN</td>
      <td>17</td>
      <td>HC16</td>
      <td>[Pièce d'identité à présenter à bord du train....</td>
      <td>TGVmax</td>
      <td>None</td>
      <td>None</td>
      <td>PT00AD</td>
      <td>6919</td>
      <td>TGD</td>
      <td>tgv</td>
      <td>2</td>
    </tr>
    <tr>
      <td>2017-11-01T10:44</td>
      <td>SN</td>
      <td>2017-11-01T07:41</td>
      <td>Grenoble</td>
      <td>Grenoble</td>
      <td>FRGNB</td>
      <td>183</td>
      <td>wdi</td>
      <td>[VEP, BAR, HAN, SMP]</td>
      <td>Paris</td>
      <td>Paris Gare de Lyon</td>
      <td>FRPLY</td>
      <td>B</td>
      <td>BN</td>
      <td>17</td>
      <td>HC16</td>
      <td>[Pièce d'identité à présenter à bord du train....</td>
      <td>TGVmax</td>
      <td>None</td>
      <td>None</td>
      <td>PT00AD</td>
      <td>6905</td>
      <td>TGS</td>
      <td>tgv</td>
      <td>2</td>
    </tr>
  </tbody>
</table>

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2017-09-13
  • 2019-10-05
  • 1970-01-01
  • 2013-02-14
  • 2023-03-14
  • 1970-01-01
  • 2011-01-29
  • 2019-01-13
相关资源
最近更新 更多