简体   繁体   English

如何使用 Python 3 将 JSON 文件转换为字典

[英]How to convert a JSON file into a dictionnary with Python 3

first post here.第一次在这里发帖。 Total newbie in Python & programming in general. Python 和编程的总体新手。

Basically I'm following this guy's tutorial (not querying the same API though) about extracting data from a JSON response in Python .基本上我正在关注这个人的教程(虽然不查询相同的 API)关于从 Python 中的 JSON 响应中提取数据

Here is my (very simple) code:这是我的(非常简单的)代码:

#!/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)

Now, instead of extracting the data marked with 'Segments' in the JSON file.现在,而不是提取 JSON 文件中标有“Segments”的数据。 I get this error:我收到此错误:

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

So, I've tried int(), to make it an integer but does not work.所以,我试过 int(),使它成为一个整数,但不起作用。

Thank you very much if you can help.如果您能提供帮助,非常感谢。

The data returned by requests.get().json() is a list of data. requests.get().json()的数据是一个数据列表。 You can iterate through the list by using a for data in json_data: loop.您可以通过for data in json_data:循环中使用for data in json_data:来遍历列表。 Then you can access the 'segments' key of the dict directly.然后您可以直接访问 dict 的“段”键。

#!/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'])

Regarding your question about the tutorial code:关于您关于教程代码的问题:

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)

The docs for the google geocoding api here (the api he is using in the video) specify that you will get a dictionary with the a specific architecture. 此处google geocoding api文档(他在视频中使用的 api)指定您将获得具有特定架构的字典。 However when you are getting your data from http://calendar.voyages-sncf.com/cdp/api they are not returning the same data structure.但是,当您从http://calendar.voyages-sncf.com/cdp/api获取数据时,它们不会返回相同的数据结构。 In their case it is a list of dictionaries.在他们的情况下,它是一个字典列表。

So every time you get new data from a different api (or a different endpoint in the same api) you will get data in a different structure.因此,每次您从不同的 api(或同一 api 中的不同端点)获取新数据时,您都会以不同的结构获取数据。 Therefor you will need to change your code to work with each piece of data.因此,您需要更改代码以处理每条数据。

JSON is simply a standard way to change a dictionary, list, or other native (native to python, java, or what ever language you are using at the time) to and from a string after it is sent over a network. JSON 只是在通过网络发送字符串后将字典、列表或其他本机(python、java 或您当时使用的任何语言的本机)更改为字符串或将其更改为字符串的标准方法。 This can lead to problems.这可能会导致问题。 Specifically in python a set() can not be changed directly to JSON.特别是在 python 中, set()不能直接更改为 JSON。 It needs to be changed to a list then to JSON, then back to a list then back to a set on the other side.它需要先更改为列表,然后更改为 JSON,然后再更改为列表,然后再更改为另一侧的集合。

The following example is was copied from the google docs here with minor modifications to make it smaller and more readable.以下示例是从此处的 google 文档复制而来,并进行了少量修改以使其更小且更具可读性。

{
   "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"
}

Welcome to SO and glad u chose Python :).欢迎来到 SO,很高兴您选择了 Python :)。

If you are new to Python and intend to work with tables do not hesitate to learn pandas .如果您是 Python 新手并打算使用表格,请不要犹豫学习pandas There are tons of documents and questions about pandas.有大量关于熊猫的文件和问题。

Examples:例子:

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)

And

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

With pandas you can output to list, dictionaries, csv, json and so on...使用 Pandas,您可以输出到列表、字典、csv、json 等...

Here is a snippet that returns html table with first 3 rows:这是一个返回带有前 3 行的 html 表的代码段:

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

Result结果

 <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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM