本文目录导读:

我来为您详细介绍Python中解析HTTP响应返回值的各种情况和方法。
使用requests库解析响应
基本JSON响应解析
import requests
# 发送请求
response = requests.get('https://api.example.com/users')
# 解析JSON响应
if response.status_code == 200:
data = response.json() # 自动解析JSON
print(f"状态码: {response.status_code}")
print(f"响应头: {response.headers}")
print(f"解析后的数据: {data}")
# 访问JSON数据
if isinstance(data, dict):
print(f"用户列表: {data.get('users', [])}")
elif isinstance(data, list):
print(f"用户数: {len(data)}")
处理不同类型的响应
import requests
import json
def parse_response(response):
"""智能解析各种类型的响应"""
# 1. 获取原始内容
content = response.content # 字节格式
text = response.text # 字符串格式
# 2. 根据Content-Type解析
content_type = response.headers.get('content-type', '').lower()
if 'application/json' in content_type:
# JSON格式
try:
return response.json()
except json.JSONDecodeError as e:
print(f"JSON解析失败: {e}")
return None
elif 'text/xml' in content_type or 'application/xml' in content_type:
# XML格式
import xml.etree.ElementTree as ET
try:
root = ET.fromstring(response.text)
return root
except ET.ParseError as e:
print(f"XML解析失败: {e}")
return None
elif 'text/html' in content_type:
# HTML格式
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
return soup
elif 'application/x-www-form-urlencoded' in content_type:
# URL编码格式
from urllib.parse import parse_qs
return parse_qs(response.text)
else:
# 文本或其他格式
return response.text
# 使用示例
response = requests.get('https://api.example.com/data')
parsed_data = parse_response(response)
print(f"解析结果类型: {type(parsed_data)}")
处理嵌套JSON响应
import requests
import json
from typing import Dict, List, Any
class ResponseParser:
"""响应解析器"""
def __init__(self, response: requests.Response):
self.response = response
self.raw_data = None
def parse_json(self) -> Dict[str, Any]:
"""解析标准JSON响应"""
try:
self.raw_data = self.response.json()
return self.raw_data
except Exception as e:
print(f"解析错误: {e}")
return {}
def extract_value(self, key_path: str, default=None):
"""
提取嵌套JSON中的值
key_path: 用点号分隔的键路径,如 'data.user.name'
"""
if not self.raw_data:
self.parse_json()
keys = key_path.split('.')
current = self.raw_data
for key in keys:
if isinstance(current, dict):
current = current.get(key)
if current is None:
return default
else:
return default
return current
def get_paginated_data(self, data_path: str, page_param: str = 'page'):
"""
处理分页数据
"""
all_data = []
page = 1
while True:
# 请求当前页
params = {page_param: page}
resp = requests.get(self.response.url, params=params)
if resp.status_code != 200:
break
# 提取当前页数据
data = resp.json()
items = self._nested_get(data, data_path)
if not items:
break
all_data.extend(items)
# 检查是否有下一页
if not self._has_next_page(data):
break
page += 1
return all_data
def _nested_get(self, data: dict, path: str):
"""内部方法:获取嵌套数据"""
keys = path.split('.')
current = data
for key in keys:
if isinstance(current, dict):
current = current.get(key)
else:
return None
return current
def _has_next_page(self, data: dict) -> bool:
"""检查是否有下一页"""
# 根据不同API的实现调整
return data.get('has_next', False) or data.get('next_page') is not None
# 使用示例
response = requests.get('https://api.example.com/users/1')
parser = ResponseParser(response)
# 解析完整数据
data = parser.parse_json()
print(f"完整数据: {json.dumps(data, indent=2, ensure_ascii=False)}")
# 提取特定字段
name = parser.extract_value('data.user.name', '未知用户')
email = parser.extract_value('data.user.contact.email')
print(f"用户名: {name}, 邮箱: {email}")
处理不同HTTP状态码
import requests
def handle_response(response: requests.Response):
"""根据状态码处理响应"""
status_code = response.status_code
if status_code == 200:
# 成功响应
try:
return response.json()
except:
return response.text
elif status_code == 201:
# 创建成功
print("资源创建成功")
return response.json()
elif status_code == 204:
# 无内容
print("操作成功,无返回内容")
return None
elif status_code == 301 or status_code == 302:
# 重定向
print(f"重定向到: {response.headers.get('Location')}")
# 可以跟随重定向
follow_response = requests.get(response.headers['Location'])
return handle_response(follow_response)
elif status_code == 400:
# 错误的请求
error_data = response.json()
print(f"请求错误: {error_data.get('message', '未知错误')}")
return {'error': error_data}
elif status_code == 401:
# 未授权
print("需要认证,请检查API密钥")
return {'error': 'Unauthorized'}
elif status_code == 403:
# 禁止访问
print("访问被拒绝")
return {'error': 'Forbidden'}
elif status_code == 404:
# 资源不存在
print("请求的资源不存在")
return {'error': 'Not Found'}
elif status_code == 429:
# 请求过多
retry_after = response.headers.get('Retry-After', '60')
print(f"请求速度过快,请在{retry_after}秒后重试")
return {'error': 'Rate Limited', 'retry_after': retry_after}
elif 500 <= status_code < 600:
# 服务器错误
print(f"服务器错误 ({status_code})")
return {'error': f'Server Error: {status_code}'}
else:
# 其他状态码
print(f"未处理的HTTP状态码: {status_code}")
return {'error': f'Unhandled status code: {status_code}'}
# 使用示例
urls = [
'https://api.example.com/success',
'https://api.example.com/not-found',
'https://api.example.com/error'
]
for url in urls:
response = requests.get(url)
result = handle_response(response)
print(f"URL: {url}")
print(f"结果: {result}\n")
异步响应解析
import aiohttp
import asyncio
import json
async def parse_async_response(session: aiohttp.ClientSession, url: str):
"""异步解析API响应"""
try:
async with session.get(url) as response:
# 获取状态码
status = response.status
# 获取响应头
headers = dict(response.headers)
# 异步获取文本内容
text = await response.text()
# 尝试解析JSON
try:
data = json.loads(text)
return {
'status': status,
'headers': headers,
'data': data,
'type': 'json'
}
except json.JSONDecodeError:
# 如果不是JSON,返回文本
return {
'status': status,
'headers': headers,
'data': text,
'type': 'text'
}
except aiohttp.ClientError as e:
print(f"请求错误: {e}")
return {'status': 0, 'error': str(e)}
async def parse_multiple_responses(urls: list):
"""并发解析多个API响应"""
async with aiohttp.ClientSession() as session:
tasks = [parse_async_response(session, url) for url in urls]
results = await asyncio.gather(*tasks)
return results
# 使用示例
async def main():
urls = [
'https://api.example.com/endpoint1',
'https://api.example.com/endpoint2'
]
results = await parse_multiple_responses(urls)
for i, result in enumerate(results):
print(f"结果 {i+1}:")
print(f" 状态: {result.get('status')}")
print(f" 类型: {result.get('type')}")
print(f" 数据: {result.get('data')}\n")
# 运行异步函数
# asyncio.run(main())
实用工具函数
import requests
import json
from datetime import datetime
def parse_api_response(response: requests.Response) -> dict:
"""通用的API响应解析函数"""
result = {
'success': False,
'status_code': response.status_code,
'data': None,
'error': None,
'meta': {}
}
try:
# 检查状态码
if response.ok:
# 尝试解析JSON
try:
result['data'] = response.json()
except ValueError:
result['data'] = response.text
result['success'] = True
# 解析响应头中的元信息
result['meta'] = {
'content_type': response.headers.get('content-type'),
'content_length': response.headers.get('content-length'),
'server': response.headers.get('server'),
'date': response.headers.get('date'),
'request_time': response.elapsed.total_seconds()
}
else:
# 错误响应
try:
error_data = response.json()
result['error'] = error_data.get('message', error_data.get('error', '未知错误'))
except ValueError:
result['error'] = response.text[:200] # 只取前200个字符
except requests.RequestException as e:
result['error'] = str(e)
return result
# 使用示例
def main():
# 模拟不同的API响应
responses = [
requests.Response(), # 空响应示例
]
api_response = parse_api_response(responses[0] if responses else requests.Response())
if api_response['success']:
print(f"请求成功!")
print(f"数据: {json.dumps(api_response['data'], indent=2)}")
print(f"元信息: {api_response['meta']}")
else:
print(f"请求失败: {api_response['error']}")
if __name__ == "__main__":
main()
这些示例涵盖了Python中解析HTTP响应的主要场景,包括:
- JSON解析:最常用的API响应格式
- 错误处理:各种HTTP状态码的适当处理
- 嵌套数据提取:从复杂JSON结构中提取值
- 分页处理:处理分页API响应
- 异步解析:提高大量请求的性能
- 通用工具函数:可复用的解析逻辑
根据您的具体需求选择合适的解析方法。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播