Keywords: Python | HTTP requests | JSON parsing | Requests library | API integration
Abstract: This article provides an in-depth exploration of how to use the Requests library in Python to send HTTP GET requests to the Google Directions API and parse the returned JSON data. Through detailed code examples, it demonstrates parameter construction, response status handling, extraction of key information from JSON, and best practices for error handling. The guide also contrasts Requests with the standard urllib library, highlighting its advantages in simplifying HTTP communications.
Introduction
In modern web development, communicating with APIs via HTTP and processing JSON responses is a common task. Python's Requests library, known for its clean API and robust features, is the preferred tool for such operations. This article delves into using the Requests library to send HTTP requests and parse JSON responses, using a practical example of querying the Google Directions API for route information.
Installing the Requests Library
The Requests library is not part of Python's standard library and must be installed via pip. Execute the following command in your terminal:
pip install requests
Once installed, you can import and use the library in your Python scripts.
Constructing an HTTP GET Request
When sending a request to the Google Directions API, you need to build a URL with query parameters. The Requests library's get method allows passing parameters as a dictionary via the params argument, automatically handling URL encoding.
import requests
url = 'http://maps.googleapis.com/maps/api/directions/json'
params = {
'origin': 'Chicago,IL',
'destination': 'Los Angeles,CA',
'waypoints': 'Joplin,MO|Oklahoma City,OK',
'sensor': 'false'
}
resp = requests.get(url=url, params=params)
This code constructs a request to query the route from Chicago to Los Angeles, with waypoints in Joplin and Oklahoma City. The sensor parameter indicates whether to use sensor data, set to false in this case.
Handling the HTTP Response
After sending the request, the server returns a response object. First, check the HTTP status code to ensure the request was successful. A status code of 200 indicates success, while other codes may signify errors.
if resp.status_code == 200:
print("Request successful")
else:
print(f"Request failed with status code: {resp.status_code}")
For non-200 status codes, you can call resp.raise_for_status() to raise an exception, facilitating error handling.
Parsing the JSON Response
The Requests library includes a built-in JSON decoder. Use the json() method to parse the response content into a Python dictionary, making it easy to access JSON data.
data = resp.json()
After parsing, the data variable contains a dictionary that mirrors the structure of the API's JSON response. For instance, the Google Directions API response may include routes, distances, and durations.
Accessing JSON Data
The parsed dictionary can be accessed like any Python dictionary. For example, to extract the total distance of the route:
# Assuming the JSON structure has a 'routes' key with 'legs' list containing 'distance' text
if 'routes' in data and len(data['routes']) > 0:
route = data['routes'][0]
if 'legs' in route and len(route['legs']) > 0:
distance = route['legs'][0]['distance']['text']
print(f"Total distance: {distance}")
This code checks for the presence of expected keys to avoid KeyError exceptions. The actual API response structure should be verified against the Google Directions API documentation.
Error Handling and Validation
Before parsing JSON, validate the response status and content type. If the response is invalid or not in JSON format, the json() method may raise a JSONDecodeError.
try:
if resp.status_code == 200:
data = resp.json()
else:
print(f"Error status code: {resp.status_code}")
except requests.exceptions.JSONDecodeError:
print("Response is not valid JSON")
This snippet combines status code checks and exception handling for robustness.
Comparison with Standard Library
Python's standard urllib module can also handle HTTP requests, but the code is more verbose. For example, using urllib for the same request:
from urllib import request, parse
url = 'http://maps.googleapis.com/maps/api/directions/json'
params = parse.urlencode({
'origin': 'Chicago,IL',
'destination': 'Los Angeles,CA',
'waypoints': 'Joplin,MO|Oklahoma City,OK',
'sensor': 'false'
})
full_url = f"{url}?{params}"
with request.urlopen(full_url) as response:
data = response.read().decode('utf-8')
# Manual JSON parsing required, e.g., using the json module
import json
parsed_data = json.loads(data)
In contrast, the Requests library simplifies parameter handling, response decoding, and error handling, enhancing development efficiency.
Complete Example Code
Below is a full script that integrates the above steps, including error handling and data processing:
import requests
def get_route_info(origin, destination, waypoints):
url = 'http://maps.googleapis.com/maps/api/directions/json'
params = {
'origin': origin,
'destination': destination,
'waypoints': waypoints,
'sensor': 'false'
}
try:
resp = requests.get(url=url, params=params)
resp.raise_for_status() # Check for HTTP errors
data = resp.json()
# Extract key information
if data.get('status') == 'OK' and 'routes' in data:
route = data['routes'][0]
summary = route.get('summary', 'No summary')
legs = route.get('legs', [])
total_distance = 0
total_duration = 0
for leg in legs:
total_distance += leg['distance']['value'] # meters
total_duration += leg['duration']['value'] # seconds
print(f"Route summary: {summary}")
print(f"Total distance: {total_distance / 1000:.2f} km")
print(f"Total duration: {total_duration / 3600:.2f} hours")
else:
print(f"API returned error: {data.get('status')}")
except requests.exceptions.RequestException as e:
print(f"Request error: {e}")
except ValueError as e:
print(f"JSON parsing error: {e}")
# Usage example
get_route_info('Chicago,IL', 'Los Angeles,CA', 'Joplin,MO|Oklahoma City,OK')
This function encapsulates the request logic, extracts distance and duration, and handles common exceptions.
Conclusion
The Requests library offers an efficient and user-friendly interface for HTTP communications in Python. Through the examples in this article, readers can master the basics of sending GET requests, handling responses, and parsing JSON data. In real-world projects, refer to specific API documentation to adapt to response structures and implement comprehensive error handling. Combining with other libraries like Beautiful Soup (for HTML parsing) or pandas (for data analysis) can further expand application scenarios.