0Pricing
AI Agents · 课时

处理 API 响应与错误

解析 JSON 响应、处理错误代码和异常。

处理 API 响应与错误 是 CoddyKit 上的免费 AI Agents 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Agents 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Agents 课程共包含 4 节课。

响应对象

每次 requests 调用都会返回一个响应对象。它包含服务器返回的所有内容:状态码、标头和正文。处理正文前,始终检查状态码——状态为 500 的响应仍然有正文,但其中不会包含您需要的数据。

import requests

response = requests.get('https://api.example.com/data')

# Key attributes of the response
print(response.status_code)       # e.g. 200
print(response.headers)           # dict of response headers
print(response.headers.get('Content-Type'))  # 'application/json'
print(response.text)              # raw response body as string
print(response.content)           # raw bytes

使用 response.json() 解析 JSON

调用 response.json() 可自动将响应正文解析为 Python 字典或列表。这等同于 json.loads(response.text),但还会验证 Content-Type 是否合适。

只有在确定响应确实是 JSON 时才调用 .json()——请先检查 Content-Type 标头。

import requests

response = requests.get(
    'https://api.example.com/users/42',
    headers={'Authorization': 'Bearer YOUR_KEY'}
)

# Parse JSON body
user = response.json()

# Access fields safely with .get()
name = user.get('name', 'Unknown')
email = user.get('email', '')
roles = user.get('roles', [])

print(f'User: {name} ({email})')
print(f'Roles: {roles}')

解析前检查 status_code

在确认请求成功之前,绝不要调用 response.json()。错误响应(4xx/5xx)通常会返回 JSON 格式的错误详情——这对调试很有用,但那不是您需要的数据。始终先检查 status_code。

import requests

response = requests.post(
    'https://api.example.com/tasks',
    json={'title': 'Write report'},
    headers={'Authorization': 'Bearer YOUR_KEY'}
)

if response.status_code == 201:
    task = response.json()
    print('Task created, ID:', task['id'])
elif response.status_code == 400:
    error = response.json()
    print('Validation error:', error.get('message'))
elif response.status_code == 401:
    print('Auth failed — check your token')
else:
    print(f'Unexpected status {response.status_code}: {response.text[:200]}')

raise_for_status()——自动引发错误

如果状态码为 4xx 或 5xx,response.raise_for_status() 会自动引发 HTTPError 异常。这是一种将错误的 HTTP 响应转换为 Python 异常的简洁方式,让您可以使用 try/except,而不必编写冗长的 if/elif 链。

import requests
from requests.exceptions import HTTPError

try:
    response = requests.get(
        'https://api.example.com/users/9999',
        headers={'Authorization': 'Bearer YOUR_KEY'}
    )
    response.raise_for_status()  # raises if status >= 400
    user = response.json()
    print('Found user:', user['name'])

except HTTPError as e:
    print(f'HTTP error: {e.response.status_code}')
    print('Details:', e.response.text[:300])

处理 JSONDecodeError

有时,API 在您预期会收到 JSON 时却返回非 JSON 响应——例如 HTML 格式的服务器错误页面、空正文或二进制文件。对这些响应调用 response.json() 会引发 json.JSONDecodeError。请始终捕获此错误,以避免代理无提示地崩溃。

import requests
import json

response = requests.get(
    'https://api.example.com/report',
    headers={'Authorization': 'Bearer YOUR_KEY'}
)

try:
    data = response.json()
except json.JSONDecodeError as e:
    print(f'Response is not valid JSON: {e}')
    print('Content-Type:', response.headers.get('Content-Type'))
    print('First 200 chars:', response.text[:200])
    # Decide: is this an HTML error page? A CSV file?
    data = None

if data is None:
    print('Falling back to text processing')

ConnectionError——网络问题

当代理完全无法连接到服务器时,就会发生 ConnectionError——例如 DNS 解析失败、服务器离线或防火墙阻止请求。这是在 HTTP 开始之前发生的网络层故障。

这不同于 5xx 响应:这不是服务器返回的响应,而是连接根本没有建立。

import requests
from requests.exceptions import ConnectionError

try:
    response = requests.get('https://api.example.com/data')
    data = response.json()
except ConnectionError as e:
    print('Cannot reach server. Possible causes:')
    print('- DNS failure (bad hostname)')
    print('- Server is down')
    print('- No internet connection')
    print('- Firewall blocking the port')
    print(f'Error detail: {e}')
    # Consider: queue the request for retry when connectivity returns

超时——防止代理卡住

默认情况下,requests 会无限等待响应。响应缓慢或卡住的服务器会让您的代理无限期地冻结。请始终设置超时:以秒为单位的 (connect_timeout, read_timeout) 元组。如果服务器未能及时响应,就会引发 Timeout 异常。

import requests
from requests.exceptions import Timeout

try:
    response = requests.get(
        'https://api.example.com/slow-endpoint',
        headers={'Authorization': 'Bearer YOUR_KEY'},
        timeout=(5, 30)  # 5s to connect, 30s to read
    )
    data = response.json()
except Timeout:
    print('Request timed out after 30 seconds')
    print('Options: retry, use cached result, or alert operator')

全面处理异常

在生产环境的代理中,请以一致的层次结构捕获所有 requests 异常。requests.exceptions.RequestException 是所有 requests 错误的基类;捕获它可以为意外的网络问题提供安全保障。

import requests
import json
from requests.exceptions import (
    ConnectionError, Timeout, HTTPError, RequestException
)

def safe_api_call(url, headers):
    try:
        r = requests.get(url, headers=headers, timeout=(5, 30))
        r.raise_for_status()
        return r.json()
    except Timeout:
        print('ERROR: Request timed out')
    except ConnectionError:
        print('ERROR: Cannot reach server')
    except HTTPError as e:
        print(f'ERROR: HTTP {e.response.status_code}')
        try:
            print('API error:', e.response.json().get('message'))
        except json.JSONDecodeError:
            print('Non-JSON error body')
    except RequestException as e:
        print(f'ERROR: Unexpected request error: {e}')
    return None

记录响应以进行调试

代理行为异常时,您需要足够的上下文来诊断问题。记录请求方法、URL、状态码和相关响应详情——但绝不要记录 API 密钥。生产环境的代理应使用 Python 内置的 logging 模块,而不是 print 语句。

import logging
import requests

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('agent.api')

def logged_request(method, url, **kwargs):
    logger.info(f'-> {method.upper()} {url}')
    response = requests.request(method, url, **kwargs)
    logger.info(
        f'<- {response.status_code} '
        f'({len(response.content)} bytes) '
        f'{response.elapsed.total_seconds():.2f}s'
    )
    if response.status_code >= 400:
        logger.error(f'Error body: {response.text[:500]}')
    return response

处理分页响应

许多 API 会按页返回数据。您的代理必须沿着分页链接获取所有结果。请查找响应中的 next URL,或查找 page/cursor 字段,并循环处理,直到没有更多页面。

import requests

def get_all_items(base_url, headers):
    all_items = []
    url = f'{base_url}/items?page=1&limit=100'

    while url:
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        data = response.json()

        all_items.extend(data.get('items', []))

        # Follow 'next' link if present
        url = data.get('next_page_url')  # None stops the loop

        print(f'Fetched {len(all_items)} items so far...')

    print(f'Total: {len(all_items)} items')
    return all_items

流式传输大型响应

对于大型响应(文件、较长的 AI 输出),请使用 stream=True,避免一次性将整个响应加载到内存中。分块读取响应。当代理处理大型数据集或流式传输 AI 生成的文本时,这一点至关重要。

import requests

response = requests.get(
    'https://api.example.com/large-report',
    headers={'Authorization': 'Bearer YOUR_KEY'},
    stream=True
)

response.raise_for_status()

# Write streamed content to file
with open('report.json', 'wb') as f:
    for chunk in response.iter_content(chunk_size=8192):
        if chunk:
            f.write(chunk)

print('Download complete')

# For streaming JSON lines (NDJSON):
for line in response.iter_lines():
    if line:
        import json
        record = json.loads(line)
        print(record)

快速检查:raise_for_status

测试您对响应错误处理的理解。

响应处理回顾

稳健的响应处理是脆弱代理与可靠代理之间的区别:

  • 解析正文前始终检查 status_code
  • 使用 response.json() 进行解析;如果正文可能不是 JSON,请捕获 JSONDecodeError
  • 使用 raise_for_status() 将 HTTP 错误转换为异常
  • 网络故障捕获 ConnectionError,服务器响应缓慢则捕获 Timeout
  • 为每个请求始终设置 timeout=(connect, read) 元组
  • 记录请求和响应(不记录密钥),以便调试

常见问题解答

「处理 API 响应与错误」课时是免费的吗?

是的 — 「处理 API 响应与错误」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Agents 课程的其余内容,请升级到 CoddyKit PRO。 AI Agents 课程共包含 4 节课。

「处理 API 响应与错误」这节课中我会学到什么?

解析 JSON 响应、处理错误代码和异常。 你通过在浏览器中直接运行的动手代码来练习 AI Agents,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Agents 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Agents 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「处理 API 响应与错误」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Agents 课中编写并运行代码吗?

能。每节 AI Agents 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 代理开发者的 REST API 基础
  2. 身份验证:API 密钥与 OAuth
  3. 处理 API 响应与错误
  4. 速率限制与重试逻辑
← 返回 AI Agents