Introduction
La polyvalence de Python s'étend au travail avec les données JSON, un format largement utilisé pour stocker et échanger des informations. Les structures JSON peuvent être simples ou complexes avec des éléments imbriqués, similaires aux dictionnaires et aux listes Python. Dans ce tutoriel, vous apprendrez comment accéder et extraire des données de structures JSON imbriquées en Python grâce à des exercices pratiques.
À la fin de ce lab, vous serez capable de naviguer avec confiance dans les objets JSON, d'accéder aux clés profondément imbriquées et de travailler avec des tableaux imbriqués dans les applications Python.
Comprendre JSON en Python
JSON (JavaScript Object Notation) est un format d'échange de données léger, à la fois lisible par l'homme et analysable par une machine. En Python, les objets JSON sont représentés comme des dictionnaires, et les tableaux JSON comme des listes.
Commençons par créer un script Python simple pour explorer les données JSON :
Ouvrez le WebIDE et créez un nouveau fichier en cliquant sur "File > New File" dans le menu.
Enregistrez le fichier sous le nom
basic_json.pydans le répertoire/home/labex/project/json_practice.Ajoutez le code suivant à
basic_json.py:
import json
## A simple JSON object (represented as a Python dictionary)
person = {
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com",
"is_employed": True,
"hobbies": ["reading", "hiking", "coding"]
}
## Convert Python dictionary to JSON string
json_string = json.dumps(person, indent=2)
print("JSON as string:")
print(json_string)
print("\n" + "-" * 50 + "\n")
## Convert JSON string back to Python dictionary
parsed_json = json.loads(json_string)
print("Python dictionary:")
print(parsed_json)
print("\n" + "-" * 50 + "\n")
## Accessing basic elements
print("Basic access examples:")
print(f"Name: {parsed_json['name']}")
print(f"Age: {parsed_json['age']}")
print(f"First hobby: {parsed_json['hobbies'][0]}")
- Exécutez le script en ouvrant un terminal dans WebIDE et en exécutant :
cd /home/labex/project/json_practice
python3 basic_json.py
Vous devriez voir la sortie suivante :
JSON as string:
{
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com",
"is_employed": true,
"hobbies": [
"reading",
"hiking",
"coding"
]
}
--------------------------------------------------
Python dictionary:
{'name': 'John Doe', 'age': 30, 'email': 'john.doe@example.com', 'is_employed': True, 'hobbies': ['reading', 'hiking', 'coding']}
--------------------------------------------------
Basic access examples:
Name: John Doe
Age: 30
First hobby: reading
Compréhension du code
json.dumps()convertit un objet Python en une chaîne formatée JSONjson.loads()analyse une chaîne JSON et la convertit en un objet Python- Pour accéder aux éléments d'un objet JSON, utilisez la syntaxe du dictionnaire :
object_name['key'] - Pour accéder aux éléments d'un tableau JSON, utilisez l'indexation de liste :
array_name[index]
Cet exemple démontre les opérations de base pour travailler avec JSON en Python. Dans l'étape suivante, nous explorerons comment accéder aux structures JSON imbriquées.
Accéder aux clés de dictionnaires imbriqués
Les objets JSON contiennent souvent des structures imbriquées. En Python, nous pouvons accéder aux données imbriquées en utilisant plusieurs crochets ou en enchaînant les clés de dictionnaire.
Créons un nouveau script pour explorer les objets JSON imbriqués :
Dans le WebIDE, créez un nouveau fichier et enregistrez-le sous le nom
nested_dict.pydans le répertoire/home/labex/project/json_practice.Ajoutez le code suivant à
nested_dict.py:
import json
## JSON with nested object
user_data = {
"name": "John Doe",
"age": 30,
"contact": {
"email": "john.doe@example.com",
"phone": "555-1234",
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"zip": "12345"
}
},
"preferences": {
"theme": "dark",
"notifications": True
}
}
## Let's prettify and print the JSON structure
print("Full JSON structure:")
print(json.dumps(user_data, indent=2))
print("\n" + "-" * 50 + "\n")
## Accessing nested elements
print("Accessing nested elements:")
print(f"Email: {user_data['contact']['email']}")
print(f"City: {user_data['contact']['address']['city']}")
print(f"Theme: {user_data['preferences']['theme']}")
print("\n" + "-" * 50 + "\n")
## Safe access with get() method
print("Safe access with get():")
## get() returns None if key doesn't exist, or a default value if specified
phone = user_data.get('contact', {}).get('phone', 'Not available')
country = user_data.get('contact', {}).get('address', {}).get('country', 'Not specified')
print(f"Phone: {phone}")
print(f"Country: {country}") ## This key doesn't exist but won't cause an error
- Exécutez le script dans le terminal :
cd /home/labex/project/json_practice
python3 nested_dict.py
Vous devriez voir une sortie similaire à :
Full JSON structure:
{
"name": "John Doe",
"age": 30,
"contact": {
"email": "john.doe@example.com",
"phone": "555-1234",
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"zip": "12345"
}
},
"preferences": {
"theme": "dark",
"notifications": true
}
}
--------------------------------------------------
Accessing nested elements:
Email: john.doe@example.com
City: Anytown
Theme: dark
--------------------------------------------------
Safe access with get():
Phone: 555-1234
Country: Not specified
Comprendre l'accès imbriqué
Lorsque vous travaillez avec des structures JSON imbriquées, vous pouvez accéder aux éléments imbriqués en enchaînant les clés avec des crochets :
## Syntax for nested access
value = json_data['key1']['key2']['key3']
Cependant, cette approche peut provoquer des erreurs si une clé de la chaîne n'existe pas. La méthode la plus sûre consiste à utiliser la fonction get(), qui vous permet de fournir une valeur par défaut si une clé est manquante :
## Safe access with get() method
value = json_data.get('key1', {}).get('key2', {}).get('key3', 'default_value')
Ce modèle d'accès sûr est particulièrement précieux lorsque vous travaillez avec des réponses d'API ou d'autres données JSON externes où la structure pourrait ne pas être cohérente.
Travailler avec des tableaux imbriqués en JSON
Les données JSON incluent souvent des tableaux (listes en Python) qui peuvent contenir d'autres objets ou tableaux. Explorons comment accéder aux éléments à l'intérieur des tableaux imbriqués.
Dans le WebIDE, créez un nouveau fichier et enregistrez-le sous le nom
nested_arrays.pydans le répertoire/home/labex/project/json_practice.Ajoutez le code suivant à
nested_arrays.py:
import json
## JSON with nested arrays
company_data = {
"name": "Tech Innovations Inc",
"founded": 2010,
"departments": [
{
"name": "Engineering",
"employees": [
{"name": "Alice Johnson", "role": "Software Engineer", "skills": ["Python", "JavaScript", "AWS"]},
{"name": "Bob Smith", "role": "DevOps Engineer", "skills": ["Docker", "Kubernetes", "Linux"]}
]
},
{
"name": "Marketing",
"employees": [
{"name": "Carol Williams", "role": "Marketing Manager", "skills": ["SEO", "Content Strategy"]},
{"name": "Dave Brown", "role": "Social Media Specialist", "skills": ["Facebook Ads", "Instagram"]}
]
}
],
"locations": ["San Francisco", "New York", "London"]
}
## Print the JSON structure
print("Company Data:")
print(json.dumps(company_data, indent=2))
print("\n" + "-" * 50 + "\n")
## Accessing elements in arrays
print("Accessing array elements:")
print(f"First location: {company_data['locations'][0]}")
print(f"Number of departments: {len(company_data['departments'])}")
print(f"First department name: {company_data['departments'][0]['name']}")
print("\n" + "-" * 50 + "\n")
## Iterating through nested arrays
print("All employees and their skills:")
for department in company_data['departments']:
dept_name = department['name']
print(f"\nDepartment: {dept_name}")
print("-" * 20)
for employee in department['employees']:
print(f" {employee['name']} ({employee['role']})")
print(f" Skills: {', '.join(employee['skills'])}")
print()
## Finding specific data in nested arrays
print("-" * 50 + "\n")
print("Finding employees with Python skills:")
for department in company_data['departments']:
for employee in department['employees']:
if "Python" in employee['skills']:
print(f" {employee['name']} in {department['name']} department")
- Exécutez le script dans le terminal :
cd /home/labex/project/json_practice
python3 nested_arrays.py
Vous devriez voir une sortie similaire à :
Company Data:
{
"name": "Tech Innovations Inc",
"founded": 2010,
"departments": [
{
"name": "Engineering",
"employees": [
{
"name": "Alice Johnson",
"role": "Software Engineer",
"skills": [
"Python",
"JavaScript",
"AWS"
]
},
{
"name": "Bob Smith",
"role": "DevOps Engineer",
"skills": [
"Docker",
"Kubernetes",
"Linux"
]
}
]
},
{
"name": "Marketing",
"employees": [
{
"name": "Carol Williams",
"role": "Marketing Manager",
"skills": [
"SEO",
"Content Strategy"
]
},
{
"name": "Dave Brown",
"role": "Social Media Specialist",
"skills": [
"Facebook Ads",
"Instagram"
]
}
]
}
],
"locations": [
"San Francisco",
"New York",
"London"
]
}
--------------------------------------------------
Accessing array elements:
First location: San Francisco
Number of departments: 2
First department name: Engineering
--------------------------------------------------
All employees and their skills:
Department: Engineering
--------------------
Alice Johnson (Software Engineer)
Skills: Python, JavaScript, AWS
Bob Smith (DevOps Engineer)
Skills: Docker, Kubernetes, Linux
Department: Marketing
--------------------
Carol Williams (Marketing Manager)
Skills: SEO, Content Strategy
Dave Brown (Social Media Specialist)
Skills: Facebook Ads, Instagram
--------------------------------------------------
Finding employees with Python skills:
Alice Johnson in Engineering department
Comprendre l'accès aux tableaux imbriqués
Travailler avec des tableaux imbriqués en JSON implique une combinaison de :
- Accès indexé : Utilisez des crochets avec un index pour accéder à des éléments de tableau spécifiques (
array[0]) - Accès aux propriétés imbriquées : Enchaînez les clés de dictionnaire et les indices de tableau (
data['departments'][0]['employees']) - Itération : Utilisez des boucles pour traiter plusieurs éléments dans les tableaux
Le modèle le plus courant pour travailler avec des tableaux imbriqués est d'utiliser des boucles for imbriquées :
for outer_item in json_data['outer_array']:
for inner_item in outer_item['inner_array']:
## Process the inner_item
print(inner_item['property'])
Cette approche vous permet de parcourir des structures imbriquées complexes et d'extraire les données spécifiques dont vous avez besoin.
Gérer les clés manquantes et la prévention des erreurs
Lorsque vous travaillez avec des structures JSON complexes, en particulier à partir de sources externes comme les API, il est important de gérer les erreurs potentielles qui surviennent lorsque des clés sont manquantes. Explorons les techniques pour accéder en toute sécurité aux données JSON imbriquées.
Dans le WebIDE, créez un nouveau fichier et enregistrez-le sous le nom
error_handling.pydans le répertoire/home/labex/project/json_practice.Ajoutez le code suivant à
error_handling.py:
import json
## JSON with inconsistent structure
api_response = {
"status": "success",
"data": {
"users": [
{
"id": 1,
"name": "John Doe",
"contact": {
"email": "john.doe@example.com",
"phone": "555-1234"
},
"roles": ["admin", "user"]
},
{
"id": 2,
"name": "Jane Smith",
## Missing contact info
"roles": ["user"]
},
{
"id": 3,
"name": "Bob Johnson",
"contact": {
## Only has email, no phone
"email": "bob.johnson@example.com"
}
## Missing roles
}
]
}
}
print("API Response Structure:")
print(json.dumps(api_response, indent=2))
print("\n" + "-" * 50 + "\n")
## Approach 1: Using try-except blocks
print("Method 1: Using try-except blocks")
print("-" * 30)
for user in api_response["data"]["users"]:
print(f"User: {user['name']}")
## Get email
try:
email = user['contact']['email']
print(f" Email: {email}")
except (KeyError, TypeError):
print(" Email: Not available")
## Get phone
try:
phone = user['contact']['phone']
print(f" Phone: {phone}")
except (KeyError, TypeError):
print(" Phone: Not available")
## Get roles
try:
roles = ", ".join(user['roles'])
print(f" Roles: {roles}")
except (KeyError, TypeError):
print(" Roles: None assigned")
print()
## Approach 2: Using get() method with defaults
print("\n" + "-" * 50 + "\n")
print("Method 2: Using get() method with defaults")
print("-" * 30)
for user in api_response["data"]["users"]:
print(f"User: {user['name']}")
## Get contact info with nested get() calls
contact = user.get('contact', {})
email = contact.get('email', 'Not available')
phone = contact.get('phone', 'Not available')
print(f" Email: {email}")
print(f" Phone: {phone}")
## Get roles with default empty list
roles = user.get('roles', [])
roles_str = ", ".join(roles) if roles else "None assigned"
print(f" Roles: {roles_str}")
print()
- Exécutez le script dans le terminal :
cd /home/labex/project/json_practice
python3 error_handling.py
Vous devriez voir une sortie similaire à :
API Response Structure:
{
"status": "success",
"data": {
"users": [
{
"id": 1,
"name": "John Doe",
"contact": {
"email": "john.doe@example.com",
"phone": "555-1234"
},
"roles": [
"admin",
"user"
]
},
{
"id": 2,
"name": "Jane Smith",
"roles": [
"user"
]
},
{
"id": 3,
"name": "Bob Johnson",
"contact": {
"email": "bob.johnson@example.com"
}
}
]
}
}
--------------------------------------------------
Method 1: Using try-except blocks
------------------------------
User: John Doe
Email: john.doe@example.com
Phone: 555-1234
Roles: admin, user
User: Jane Smith
Email: Not available
Phone: Not available
Roles: user
User: Bob Johnson
Email: bob.johnson@example.com
Phone: Not available
Roles: None assigned
--------------------------------------------------
Method 2: Using get() method with defaults
------------------------------
User: John Doe
Email: john.doe@example.com
Phone: 555-1234
Roles: admin, user
User: Jane Smith
Email: Not available
Phone: Not available
Roles: user
User: Bob Johnson
Email: bob.johnson@example.com
Phone: Not available
Roles: None assigned
Comprendre les techniques de gestion des erreurs
L'exemple démontre deux approches principales pour accéder en toute sécurité aux données JSON imbriquées :
Blocs Try-Except
- Enveloppez l'accès potentiellement risqué dans des blocs try-except
- Interceptez KeyError (clé de dictionnaire manquante) et TypeError (tentative d'accès à une clé sur un non-dictionnaire)
- Fournissez des valeurs de repli lorsque des erreurs se produisent
Méthode get() enchaînée
- Utilisez la méthode get() du dictionnaire qui prend une valeur par défaut comme deuxième argument
- Enchaînez plusieurs appels get() pour les structures imbriquées
- Fournit un code plus propre sans gestion des exceptions
L'approche de la méthode get() est généralement préférée pour sa lisibilité et sa concision lors du traitement des structures JSON imbriquées. Elle vous permet de fournir des valeurs par défaut à chaque niveau d'imbrication.
## Safe nested access pattern
value = data.get('level1', {}).get('level2', {}).get('level3', 'default_value')
L'utilisation de ces techniques de gestion des erreurs rendra votre code plus robuste lorsque vous travaillerez avec des données JSON provenant de diverses sources.
Exercice pratique : Création d'un extracteur de données JSON
Mettons vos connaissances en pratique en créant un programme qui extrait des informations spécifiques d'une structure JSON complexe. Cela pourrait représenter un scénario réel où vous recevez des données JSON d'une API et devez les traiter.
Dans le WebIDE, créez un nouveau fichier et enregistrez-le sous le nom
json_extractor.pydans le répertoire/home/labex/project/json_practice.Ajoutez le code suivant à
json_extractor.py:
import json
## A complex nested JSON structure (e.g., from a weather API)
weather_data = {
"location": {
"name": "New York",
"region": "New York",
"country": "United States of America",
"lat": 40.71,
"lon": -74.01,
"timezone": "America/New_York"
},
"current": {
"temp_c": 22.0,
"temp_f": 71.6,
"condition": {
"text": "Partly cloudy",
"icon": "//cdn.weatherapi.com/weather/64x64/day/116.png",
"code": 1003
},
"wind_mph": 6.9,
"wind_kph": 11.2,
"wind_dir": "ENE",
"humidity": 65,
"cloud": 75,
"feelslike_c": 22.0,
"feelslike_f": 71.6
},
"forecast": {
"forecastday": [
{
"date": "2023-09-20",
"day": {
"maxtemp_c": 24.3,
"maxtemp_f": 75.7,
"mintemp_c": 18.6,
"mintemp_f": 65.5,
"condition": {
"text": "Patchy rain possible",
"icon": "//cdn.weatherapi.com/weather/64x64/day/176.png",
"code": 1063
},
"daily_chance_of_rain": 85
},
"astro": {
"sunrise": "06:41 AM",
"sunset": "07:01 PM",
"moonrise": "10:15 AM",
"moonset": "08:52 PM"
},
"hour": [
{
"time": "2023-09-20 00:00",
"temp_c": 20.1,
"condition": {
"text": "Clear",
"icon": "//cdn.weatherapi.com/weather/64x64/night/113.png",
"code": 1000
},
"chance_of_rain": 0
},
{
"time": "2023-09-20 12:00",
"temp_c": 23.9,
"condition": {
"text": "Overcast",
"icon": "//cdn.weatherapi.com/weather/64x64/day/122.png",
"code": 1009
},
"chance_of_rain": 20
}
]
},
{
"date": "2023-09-21",
"day": {
"maxtemp_c": 21.2,
"maxtemp_f": 70.2,
"mintemp_c": 16.7,
"mintemp_f": 62.1,
"condition": {
"text": "Heavy rain",
"icon": "//cdn.weatherapi.com/weather/64x64/day/308.png",
"code": 1195
},
"daily_chance_of_rain": 92
},
"astro": {
"sunrise": "06:42 AM",
"sunset": "06:59 PM",
"moonrise": "11:30 AM",
"moonset": "09:15 PM"
}
}
]
}
}
def extract_weather_summary(data):
"""
Extract and format a weather summary from the provided data.
"""
try:
## Location information
location = data.get("location", {})
location_name = location.get("name", "Unknown")
country = location.get("country", "Unknown")
## Current weather
current = data.get("current", {})
temp_c = current.get("temp_c", "N/A")
temp_f = current.get("temp_f", "N/A")
condition = current.get("condition", {}).get("text", "Unknown")
humidity = current.get("humidity", "N/A")
## Forecast
forecast_days = data.get("forecast", {}).get("forecastday", [])
## Build summary string
summary = f"Weather Summary for {location_name}, {country}\n"
summary += f"==================================================\n\n"
summary += f"Current Conditions:\n"
summary += f" Temperature: {temp_c}°C ({temp_f}°F)\n"
summary += f" Condition: {condition}\n"
summary += f" Humidity: {humidity}%\n\n"
if forecast_days:
summary += "Forecast:\n"
for day_data in forecast_days:
date = day_data.get("date", "Unknown date")
day = day_data.get("day", {})
max_temp = day.get("maxtemp_c", "N/A")
min_temp = day.get("mintemp_c", "N/A")
condition = day.get("condition", {}).get("text", "Unknown")
rain_chance = day.get("daily_chance_of_rain", "N/A")
summary += f" {date}:\n"
summary += f" High: {max_temp}°C, Low: {min_temp}°C\n"
summary += f" Condition: {condition}\n"
summary += f" Chance of Rain: {rain_chance}%\n"
## Get sunrise and sunset times if available
astro = day_data.get("astro", {})
if astro:
sunrise = astro.get("sunrise", "N/A")
sunset = astro.get("sunset", "N/A")
summary += f" Sunrise: {sunrise}, Sunset: {sunset}\n"
summary += "\n"
return summary
except Exception as e:
return f"Error extracting weather data: {str(e)}"
## Print the full JSON data
print("Original Weather Data:")
print(json.dumps(weather_data, indent=2))
print("\n" + "-" * 60 + "\n")
## Extract and print the weather summary
weather_summary = extract_weather_summary(weather_data)
print(weather_summary)
## Save the summary to a file
with open("weather_summary.txt", "w") as file:
file.write(weather_summary)
print("\nWeather summary has been saved to 'weather_summary.txt'")
- Exécutez le script dans le terminal :
cd /home/labex/project/json_practice
python3 json_extractor.py
- Après avoir exécuté le script, vous pouvez afficher le fichier de résumé généré :
cat weather_summary.txt
Vous verrez le résumé météorologique formaté extrait de la structure JSON complexe.
Comprendre l'extracteur JSON
Cet exercice pratique démontre plusieurs concepts importants pour travailler avec des données JSON imbriquées :
Extraction sécurisée des données
- Utilisation de la méthode
get()avec des valeurs par défaut pour gérer les clés manquantes - Accès aux données imbriquées avec des appels
get()enchaînés - Gestion des erreurs avec des blocs try-except
- Utilisation de la méthode
Transformation des données
- Conversion des données JSON en un format lisible par l'homme
- Itération à travers des tableaux imbriqués pour traiter plusieurs éléments
- Extraction uniquement des informations pertinentes d'une structure complexe
Programmation défensive
- Anticiper et gérer les problèmes potentiels
- Fournir des valeurs par défaut lorsque des données sont manquantes
- Intercepter les exceptions pour éviter les plantages du programme
Ce modèle d'extraction, de transformation et de présentation des données JSON est courant dans de nombreuses applications réelles, telles que :
- Traitement des réponses d'API
- Génération de rapports à partir de données
- Filtrage et affichage d'informations pour les utilisateurs
En suivant ces modèles, vous pouvez travailler de manière fiable avec des données JSON de toute complexité.
Résumé
Dans ce laboratoire, vous avez appris à travailler avec des structures JSON imbriquées en Python :
Gestion de base du JSON - Conversion entre les objets Python et les chaînes JSON en utilisant
json.dumps()etjson.loads().Accès aux clés de dictionnaire imbriquées - Utilisation de la notation en chaîne avec des crochets pour accéder aux valeurs profondément imbriquées dans les objets JSON.
Utilisation des tableaux imbriqués - Navigation et extraction de données à partir de tableaux au sein de structures JSON en utilisant l'indexation et l'itération.
Techniques de gestion des erreurs - Mise en œuvre de schémas d'accès sécurisés avec des blocs try-except et la méthode
get()pour gérer les clés manquantes.Extraction pratique des données - Construction d'une application complète qui extrait, transforme et présente des données à partir d'une structure JSON complexe.
Ces compétences sont essentielles pour travailler avec des données provenant d'API, de fichiers de configuration et d'autres scénarios d'échange de données. Vous avez maintenant les bases pour gérer en toute confiance les données JSON de toute complexité dans vos applications Python.
Pour un apprentissage plus approfondi, envisagez d'explorer :
- Travailler avec des API réelles qui renvoient des données JSON
- Utiliser des bibliothèques comme
pandaspour analyser les données JSON - Mettre en œuvre la validation JSON avec
jsonschema - Créer et manipuler des structures JSON personnalisées



