Python JSON Parsing: Complete Guide with Examples
JSON is everywhere in modern Python development. Whether you're building APIs, processing data, or working with configuration files, you'll need to master JSON handling. This guide covers everything from basics to advanced techniques.
Quick Start: The json Module
Python's built-in json module handles all JSON operations:
import json
# Parse JSON string to Python object
json_string = '{"name": "Alice", "age": 30}'
data = json.loads(json_string)
print(data["name"]) # Output: Alice
# Convert Python object to JSON string
python_dict = {"name": "Bob", "age": 25}
json_string = json.dumps(python_dict)
print(json_string) # Output: {"name": "Bob", "age": 25}
Core Functions
json.loads() - Parse JSON String
import json
# Basic parsing
data = json.loads('{"users": [{"id": 1, "name": "John"}]}')
print(data["users"][0]["name"]) # John
# Handle different data types
json_data = '''
{
"string": "hello",
"number": 42,
"float": 3.14,
"boolean": true,
"null_value": null,
"array": [1, 2, 3],
"object": {"nested": "value"}
}
'''
parsed = json.loads(json_data)
print(type(parsed["boolean"])) # <class 'bool'>
json.dumps() - Convert to JSON String
import json
data = {
"name": "Alice",
"skills": ["Python", "JavaScript"],
"active": True,
"score": None
}
# Basic conversion
json_string = json.dumps(data)
print(json_string)
# Pretty printing with indentation
pretty_json = json.dumps(data, indent=2)
print(pretty_json)
# Sort keys alphabetically
sorted_json = json.dumps(data, sort_keys=True, indent=2)
Working with Files
Reading JSON Files
import json
# Method 1: Using json.load()
with open('data.json', 'r') as file:
data = json.load(file)
print(data)
# Method 2: Read then parse
with open('data.json', 'r') as file:
content = file.read()
data = json.loads(content)
Writing JSON Files
import json
data = {
"users": [
{"id": 1, "name": "Alice", "email": "alice@example.com"},
{"id": 2, "name": "Bob", "email": "bob@example.com"}
]
}
# Method 1: Using json.dump()
with open('output.json', 'w') as file:
json.dump(data, file, indent=2)
# Method 2: Convert then write
with open('output.json', 'w') as file:
json_string = json.dumps(data, indent=2)
file.write(json_string)
Error Handling
Always handle JSON parsing errors gracefully:
import json
def safe_json_parse(json_string):
try:
return json.loads(json_string)
except json.JSONDecodeError as e:
print(f"JSON parsing error: {e}")
return None
# Test with invalid JSON
invalid_json = '{"name": "Alice", "age":}' # Missing value
result = safe_json_parse(invalid_json)
# More specific error handling
def parse_with_details(json_string):
try:
return json.loads(json_string)
except json.JSONDecodeError as e:
print(f"Error at line {e.lineno}, column {e.colno}")
print(f"Error message: {e.msg}")
return None
Advanced Techniques
Custom JSON Encoder
import json
from datetime import datetime
class DateTimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
data = {
"name": "Alice",
"created_at": datetime.now()
}
# Use custom encoder
json_string = json.dumps(data, cls=DateTimeEncoder, indent=2)
print(json_string)
Custom JSON Decoder
import json
from datetime import datetime
def datetime_parser(dct):
for key, value in dct.items():
if key.endswith('_at') and isinstance(value, str):
try:
dct[key] = datetime.fromisoformat(value)
except ValueError:
pass
return dct
json_string = '{"name": "Alice", "created_at": "2024-01-15T10:30:00"}'
data = json.loads(json_string, object_hook=datetime_parser)
print(type(data["created_at"])) # <class 'datetime.datetime'>
Working with APIs
Fetching and Parsing API Data
import json
import urllib.request
def fetch_json_data(url):
try:
with urllib.request.urlopen(url) as response:
data = json.loads(response.read().decode())
return data
except Exception as e:
print(f"Error fetching data: {e}")
return None
# Example usage
# data = fetch_json_data('https://api.example.com/users')
# Using requests library (recommended)
import requests
def fetch_with_requests(url):
try:
response = requests.get(url)
response.raise_for_status() # Raise exception for bad status codes
return response.json() # Automatically parses JSON
except requests.exceptions.RequestException as e:
print(f"Request error: {e}")
return None
Performance Tips
Large JSON Files
import json
# For large files, consider streaming
def process_large_json(filename):
with open(filename, 'r') as file:
# Load in chunks or use ijson for streaming
data = json.load(file)
# Process data in batches
if isinstance(data, list):
batch_size = 1000
for i in range(0, len(data), batch_size):
batch = data[i:i + batch_size]
# Process batch
yield batch
# Memory-efficient processing
for batch in process_large_json('large_data.json'):
# Process each batch
pass
Common Pitfalls
1. Trailing Commas
# Invalid JSON (trailing comma)
invalid = '{"name": "Alice", "age": 30,}'
# Valid JSON
valid = '{"name": "Alice", "age": 30}'
2. Single Quotes
# Invalid JSON (single quotes)
invalid = "{'name': 'Alice'}"
# Valid JSON (double quotes)
valid = '{"name": "Alice"}'
3. Python None vs JSON null
import json
data = {"value": None}
json_string = json.dumps(data)
print(json_string) # {"value": null}
parsed = json.loads(json_string)
print(parsed["value"] is None) # True
Try It Online
Want to test JSON parsing without setting up Python? Use our online tools:
- Python Compiler Online - Run Python code with JSON in your browser
- JSON Formatter - Format and validate JSON
- JSON Validator - Check JSON syntax
Best Practices
- Always handle exceptions when parsing JSON
- Validate data structure after parsing
- Use appropriate encoding (UTF-8) for file operations
- Consider memory usage for large JSON files
- Use type hints for better code documentation
Conclusion
Python's json module provides everything you need for JSON handling. Start with the basics (loads/dumps), add proper error handling, and gradually incorporate advanced techniques as needed. Practice with real-world APIs and data to build confidence.