第159集_API接口调用

一、API接口的基本概念

API(Application Programming Interface,应用程序编程接口)是不同软件系统之间进行交互的桥梁。在Web开发和数据获取领域,API通常指的是Web API,允许开发者通过HTTP请求访问服务器上的数据和功能。

1. API的类型

  • RESTful API:基于REST架构风格的API,使用HTTP方法(GET、POST、PUT、DELETE等)进行操作
  • SOAP API:基于XML协议的API,主要用于企业级应用集成
  • GraphQL API:一种查询语言,允许客户端精确获取所需数据

2. RESTful API的特点

  • 使用HTTP方法表示操作类型
  • 资源通过URL进行标识
  • 使用HTTP状态码表示响应结果
  • 支持多种数据格式(JSON、XML等),JSON是最常用的格式

二、使用requests库调用API

Python中的requests库是调用API的常用工具,它提供了简洁易用的API接口。

1. 安装requests库

pip install requests

2. 发送GET请求获取数据

GET请求是最常用的请求方法,用于从服务器获取数据。

import requests

# 发送GET请求
response = requests.get('https://api.github.com/users/octocat/repos')

# 检查响应状态码
if response.status_code == 200:
    # 获取响应数据(JSON格式)
    repos = response.json()
    print(f"获取到{len(repos)}个仓库")
    for repo in repos[:5]:  # 输出前5个仓库
        print(f"仓库名称: {repo['name']}")
        print(f"描述: {repo.get('description', '无描述')}")
        print(f"星标数: {repo['stargazers_count']}")
        print("-" * 50)
else:
    print(f"请求失败,状态码: {response.status_code}")

3. 发送POST请求提交数据

POST请求用于向服务器提交数据,常用于创建新资源。

import requests
import json

# 准备要提交的数据
new_post = {
    'title': '测试API POST请求',
    'body': '这是一个通过Python requests库发送的POST请求示例',
    'userId': 1
}

# 发送POST请求
response = requests.post(
    'https://jsonplaceholder.typicode.com/posts',
    data=json.dumps(new_post),
    headers={'Content-Type': 'application/json'}
)

# 或者更简单的方式
# response = requests.post('https://jsonplaceholder.typicode.com/posts', json=new_post)

if response.status_code == 201:  # 201表示资源创建成功
    created_post = response.json()
    print(f"资源创建成功,ID: {created_post['id']}")
    print(f"创建的资源: {created_post}")
else:
    print(f"请求失败,状态码: {response.status_code}")

三、API认证与授权

许多API需要认证才能访问,常见的认证方式包括:

1. API Key认证

import requests

# API Key认证示例
api_key = 'your_api_key_here'
url = f'https://api.example.com/data?api_key={api_key}'
response = requests.get(url)

2. OAuth 2.0认证

import requests

# OAuth 2.0认证示例
token = 'your_oauth_token_here'
headers = {'Authorization': f'Bearer {token}'}
url = 'https://api.example.com/protected-resource'
response = requests.get(url, headers=headers)

3. 基本认证

import requests
from requests.auth import HTTPBasicAuth

# 基本认证示例
url = 'https://api.example.com/protected-resource'
response = requests.get(url, auth=HTTPBasicAuth('username', 'password'))

四、请求参数处理

API通常支持通过查询参数过滤、排序和分页数据。

import requests

# 带查询参数的GET请求示例
params = {
    'q': 'python',  # 搜索关键词
    'sort': 'stars',  # 按星标排序
    'order': 'desc',  # 降序排列
    'per_page': 10  # 每页10条结果
}

response = requests.get('https://api.github.com/search/repositories', params=params)

if response.status_code == 200:
    data = response.json()
    print(f"搜索到{data['total_count']}个仓库")
    print("\n前10个仓库:")
    for repo in data['items']:
        print(f"名称: {repo['name']}")
        print(f"星标数: {repo['stargazers_count']}")
        print(f"语言: {repo.get('language', '未知')}")
        print("-" * 50)

五、响应解析与处理

API响应通常是JSON格式的数据,我们需要将其解析为Python对象进行处理。

1. JSON响应解析

import requests

response = requests.get('https://jsonplaceholder.typicode.com/users')

if response.status_code == 200:
    users = response.json()
    
    # 处理用户数据
    print("用户列表:")
    for user in users:
        print(f"ID: {user['id']}")
        print(f"姓名: {user['name']}")
        print(f"邮箱: {user['email']}")
        print(f"公司: {user['company']['name']}")
        print("-" * 50)

2. XML响应解析

如果API返回XML格式的数据,可以使用xml.etree.ElementTree库进行解析。

import requests
import xml.etree.ElementTree as ET

response = requests.get('https://www.w3schools.com/xml/note.xml')

if response.status_code == 200:
    # 解析XML数据
    root = ET.fromstring(response.content)
    
    # 提取数据
    to = root.find('to').text
    from_ = root.find('from').text
    heading = root.find('heading').text
    body = root.find('body').text
    
    print(f"收件人: {to}")
    print(f"发件人: {from_}")
    print(f"标题: {heading}")
    print(f"内容: {body}")

六、错误处理

在调用API时,应该处理各种可能的错误情况。

import requests
import time

def call_api_with_retry(url, max_retries=3, retry_delay=1):
    """带重试机制的API调用函数"""
    for attempt in range(max_retries):
        try:
            response = requests.get(url, timeout=10)
            
            # 检查响应状态码
            response.raise_for_status()  # 抛出HTTPError异常
            
            return response.json()
        except requests.exceptions.Timeout:
            print(f"请求超时,第{attempt+1}次重试...")
        except requests.exceptions.ConnectionError:
            print(f"连接错误,第{attempt+1}次重试...")
        except requests.exceptions.HTTPError as e:
            print(f"HTTP错误: {e}")
            if response.status_code >= 500:  # 服务器错误,可能需要重试
                print(f"服务器错误,第{attempt+1}次重试...")
            else:
                raise  # 客户端错误,不需要重试
        except requests.exceptions.JSONDecodeError:
            print("JSON解析错误")
            return None
        
        # 重试延迟
        time.sleep(retry_delay)
    
    print(f"已达到最大重试次数({max_retries})")
    return None

# 使用带重试机制的函数调用API
data = call_api_with_retry('https://api.github.com/users/octocat/repos')
if data:
    print(f"成功获取到{len(data)}个仓库")

七、API调用最佳实践

  1. 遵守API使用限制:注意API的速率限制(Rate Limit),避免频繁请求导致IP被封禁
  2. 使用合适的HTTP方法:GET用于获取数据,POST用于创建资源,PUT用于更新资源,DELETE用于删除资源
  3. 设置合理的超时时间:避免请求无限期等待
  4. 处理错误情况:包括网络错误、超时、HTTP错误等
  5. 使用认证和授权:确保API调用的安全性
  6. 缓存响应数据:对于不经常变化的数据,可以缓存响应结果,减少API调用次数
  7. 使用异步请求:对于大量API调用,可以使用异步请求提高效率

八、实际案例:天气API调用

以下是一个调用OpenWeatherMap API获取天气信息的完整示例:

import requests
import os
from dotenv import load_dotenv

# 加载环境变量(用于存储API密钥)
load_dotenv()

# 获取API密钥
api_key = os.getenv('OPENWEATHER_API_KEY')
if not api_key:
    print("请设置OPENWEATHER_API_KEY环境变量")
    exit()

# 城市名称
city = 'Beijing'

# 构建API URL
url = f'https://api.openweathermap.org/data/2.5/weather'
params = {
    'q': city,
    'appid': api_key,
    'units': 'metric',  # 使用摄氏度
    'lang': 'zh_cn'  # 使用中文
}

try:
    # 发送请求
    response = requests.get(url, params=params)
    response.raise_for_status()  # 检查是否有HTTP错误
    
    # 解析响应数据
    weather_data = response.json()
    
    # 提取天气信息
    city_name = weather_data['name']
    weather_desc = weather_data['weather'][0]['description']
    temperature = weather_data['main']['temp']
    feels_like = weather_data['main']['feels_like']
    humidity = weather_data['main']['humidity']
    wind_speed = weather_data['wind']['speed']
    
    # 输出天气信息
    print(f"城市: {city_name}")
    print(f"天气描述: {weather_desc}")
    print(f"温度: {temperature}°C")
    print(f"体感温度: {feels_like}°C")
    print(f"湿度: {humidity}%")
    print(f"风速: {wind_speed} m/s")
    
except requests.exceptions.HTTPError as e:
    print(f"HTTP错误: {e}")
except requests.exceptions.ConnectionError:
    print("连接错误,请检查网络")
except requests.exceptions.Timeout:
    print("请求超时")
except Exception as e:
    print(f"发生其他错误: {e}")

九、总结

API接口调用是现代Python开发中的重要技能,特别是在数据获取、Web开发和系统集成方面。本集我们学习了:

  1. API接口的基本概念和RESTful API的特点
  2. 使用requests库发送GET和POST请求
  3. 各种API认证和授权方式
  4. 请求参数处理和响应解析
  5. API调用的错误处理和重试机制
  6. API调用的最佳实践

通过掌握这些知识,你可以高效地与各种Web服务和API进行交互,获取和处理所需的数据。

« 上一篇 动态网页爬取 下一篇 » 爬虫项目实战