目录
- WebService 基础概念
- 什么是 WebService?
- 主要协议:SOAP vs. REST
- 调用 RESTful WebService (最常用)
- 使用
requests库 - 示例:GET 请求和 POST 请求
- 处理响应(JSON)
- 使用
- 调用 SOAP WebService
- 使用
zeep库 - 示例:连接 WSDL 并调用方法
- 使用
- 调用其他类型的 API
- XML-RPC (使用
xmlrpc.client)
- XML-RPC (使用
- 高级主题与最佳实践
- 异常处理
- 会话管理
- 超时设置
- 认证(API Key, OAuth)
- 总结与如何选择
WebService 基础概念
什么是 WebService?
WebService 是一种通过网络进行应用程序间通信的技术,它允许不同平台、不同语言的应用程序通过标准的 Web 协议(如 HTTP/HTTPS)进行数据交换,你可以把它想象成一个“远程函数”,你的程序可以调用它,并获取返回结果,而不需要关心它具体是如何实现的。

主要协议:SOAP vs. REST
这是理解如何调用 WebService 的关键。
| 特性 | SOAP (Simple Object Access Protocol) | REST (Representational State Transfer) |
|---|---|---|
| 协议 | 严格的协议,基于 XML,消息格式是固定的 SOAP Envelope。 | 一种架构风格,没有严格的协议,通常基于 HTTP。 |
| 数据格式 | 严格要求使用 XML。 | 非常灵活,常用 JSON、XML、HTML、纯文本等,JSON 因其轻量级而最受欢迎。 |
| 标准 | 有很多标准,如 WS-Security (安全)、WS-Addressing (寻址)等,功能强大。 | 没有官方标准,依赖于 HTTP 标准 (GET, POST, PUT, DELETE)。 |
| 性能 | XML 格式冗长,解析开销大,性能相对较低。 | 数据格式轻量(尤其是 JSON),传输快,性能高。 |
| 使用场景 | 企业级应用、金融、电信等对安全性、事务性要求高的场景。 | 公共 API、移动应用后端、微服务等绝大多数现代 Web 应用。 |
REST API 是绝对的主流,绝大多数新的 WebService 都采用 REST 风格,SOAP 则多用于遗留系统或特定行业,掌握 requests 调用 REST API 是最重要的。
调用 RESTful WebService (使用 requests 库)
requests 是 Python 中最著名、最易用的 HTTP 库,没有之一,它是调用 REST API 的首选。
安装 requests
pip install requests
示例 1:GET 请求(获取数据)
假设我们要调用一个公共的天气 API(这里使用 jsonplaceholder 作为示例,它是一个免费的在线测试 API)。

import requests
import json # 用于美化打印 JSON
# API 的 URL
url = "https://jsonplaceholder.typicode.com/posts/1"
try:
# 发送 GET 请求
# timeout 参数非常重要,可以防止程序因网络问题而无限期挂起
response = requests.get(url, timeout=10)
# 检查请求是否成功 (状态码 200-299 表示成功)
response.raise_for_status()
# 获取响应内容,并解析为 Python 字典
# response.json() 会自动将 JSON 响应内容转换为 Python 对象
data = response.json()
# 打印获取到的数据
print("请求成功!")
print("响应数据 (JSON 格式):")
print(json.dumps(data, indent=4, ensure_ascii=False))
# 访问特定的数据
print(f"\n用户 ID: {data['userId']}")
print(f"标题: {data['title']}")
except requests.exceptions.HTTPError as http_err:
print(f"HTTP 错误发生: {http_err}")
except requests.exceptions.ConnectionError as conn_err:
print(f"连接错误发生: {conn_err}")
except requests.exceptions.Timeout as timeout_err:
print(f"请求超时: {timeout_err}")
except requests.exceptions.RequestException as err:
print(f"发生了一个未知错误: {err}")
示例 2:POST 请求(发送数据)
import requests
import json
# API 的 URL
url = "https://jsonplaceholder.typicode.com/posts"
# 要发送的数据 (一个 Python 字典)
payload = {: 'foo',
'body': 'bar',
'userId': 1
}
# 请求头,告诉服务器我们发送的是 JSON 数据
headers = {
'Content-Type': 'application/json; charset=UTF-8'
}
try:
# 发送 POST 请求
# data=json.dumps(payload) 将 Python 字典转换为 JSON 字符串
response = requests.post(url, data=json.dumps(payload), headers=headers, timeout=10)
# 检查请求是否成功
response.raise_for_status()
# 获取服务器返回的创建的资源数据
created_data = response.json()
print("POST 请求成功!")
print("服务器返回的新创建的数据:")
print(json.dumps(created_data, indent=4, ensure_ascii=False))
except requests.exceptions.RequestException as err:
print(f"发生了一个错误: {err}")
调用 SOAP WebService (使用 zeep 库)
SOAP 服务通常通过一个 WSDL (Web Services Description Language) 文件来描述其接口,WSDL 文件定义了可用的方法、参数和返回值的结构。
安装 zeep
pip install zeep
示例:调用一个公共的 SOAP WebService
这里我们使用 ws.cdyne.com 提供的天气查询服务作为示例。
from zeep import Client
from zeep.transports import Transport
from requests import Session
# WSDL 文件的 URL
wsdl_url = "http://wsf.cdyne.com/WeatherWS/Weather.asmx?wsdl"
try:
# (可选) 设置超时
session = Session()
session.timeout = 10 # 超时时间,单位:秒
transport = Transport(session=session)
# 创建 zeep 客户端
# wsdl 参数指定 WSDL 地址
# transport 参数用于自定义传输层,如设置超时
client = Client(wsdl=wsdl_url, transport=transport)
# 查看服务提供的方法
print("可用的服务端口:")
print(client.wsdl.services)
print("\n可用的操作:")
print(client.wsdl.services['WeatherSoap']['WeatherSoap'].ports)
# 调用 WSDL 中定义的方法
# 方法名可以直接通过客户端对象访问
# 参数名必须与 WSDL 中定义的一致
response = client.service.GetCityWeatherByZIP('10001') # 使用纽约的邮编
# 打印响应结果
# SOAP 响应通常是一个复杂对象,zeep 会将其转换为 Python 的字典或对象
print("\nSOAP 响应结果:")
if response.Success:
print(f"城市: {response.City}")
print(f"状态: {response.State}")
print(f"温度: {response.Temperature}°F")
print(f"描述: {response.Description}")
else:
print(f"查询失败: {response.ResponseText}")
except Exception as e:
print(f"调用 SOAP 服务时发生错误: {e}")
调用其他类型的 API (XML-RPC)
XML-RPC 是一种更简单的远程过程调用协议,使用 XML 编码数据,通过 HTTP 传输,Python 标准库就包含了 xmlrpc.client 模块。
import xmlrpc.client
# API 的 URL
server_url = "https://requestbin.net/r/your-dump-bin-id" # 注意:这是一个示例,你需要一个真实的 XML-RPC 服务器
try:
# 创建代理
proxy = xmlrpc.client.ServerProxy(server_url)
# 调用服务器上的方法
# 假设服务器有一个名为 'add' 的方法
result = proxy.add(2, 3)
print(f"调用 add(2, 3) 的结果是: {result}")
# 调用另一个方法,'listMethods'
methods = proxy.system.listMethods()
print(f"服务器支持的方法列表: {methods}")
except xmlrpc.client.Fault as err:
print("一个 XML-RPC 错误发生:")
print(f"Fault code: {err.faultCode}")
print(f"Fault string: {err.faultString}")
except OSError as err:
print(f"网络错误发生: {err}")
except Exception as e:
print(f"发生了一个未知错误: {e}")
高级主题与最佳实践
异常处理
网络调用是不可靠的,必须处理各种异常:

requests.exceptions.RequestException:requests库中所有异常的基类。requests.exceptions.HTTPError: HTTP 错误 (4xx, 5xx)。requests.exceptions.ConnectionError: 网络连接问题。requests.exceptions.Timeout: 请求超时。zeep.exceptions.Fault: SOAP 调用中的错误。
会话管理 (requests.Session)
如果你需要向同一个域名的多个接口发送请求,使用 Session 对象可以复用 TCP 连接,提高性能,并可以统一设置 cookies 或 headers。
import requests
# 创建一个会话对象
with requests.Session() as session:
# 设置会话级别的 headers
session.headers.update({'User-Agent': 'MyPythonApp/1.0'})
# 第一次请求
response1 = session.get('https://httpbin.org/cookies/set/testname/testvalue')
print("第一次请求后的 Cookies:", response1.cookies.get_dict())
# 第二次请求会自动带上第一次设置的 cookies
response2 = session.get('https://httpbin.org/cookies')
print("第二次请求获取到的 Cookies:", response2.json())
超时设置
timeout 参数至关重要,它可以防止你的程序因网络延迟或服务器无响应而卡死。
requests.get(url, timeout=5): 5秒后连接超时。requests.get(url, timeout=(3.05, 27)): 3.05秒后连接超时,27秒后读取超时。
认证
许多 WebService 需要认证。
-
API Key (最常见):
api_key = "YOUR_API_KEY" headers = {'Authorization': f'Bearer {api_key}'} response = requests.get('https://api.example.com/data', headers=headers) -
Basic Auth (用户名/密码):
from requests.auth import HTTPBasicAuth response = requests.get('https://api.example.com/data', auth=HTTPBasicAuth('username', 'password')) # 或者更简单 response = requests.get('https://api.example.com/data', auth=('username', 'password')) -
OAuth 2.0 (复杂): 通常需要使用专门的库如
requests-oauthlib来处理授权流程。
总结与如何选择
| 场景 | 推荐库/方法 | 理由 |
|---|---|---|
| 调用现代 REST API | requests |
事实上的标准,简单、强大、文档齐全、社区活跃。 |
| 调用传统 SOAP WebService | zeep |
自动解析 WSDL,将 SOAP 操作映射为 Python 方法,使用极其方便。 |
| 调用内部 XML-RPC 服务 | xmlrpc.client |
Python 标准库,无需安装,适用于遗留系统。 |
| 需要高性能或异步调用 | httpx, aiohttp |
httpx 是 requests 的现代替代品,支持同步和异步。aiohttp 是专门为异步设计的。 |
| 需要生成客户端代码 | wsdl2py (SOAP) |
对于复杂的 SOAP 服务,可以先从 WSDL 生成 Python 客户端代码,简化调用。 |
最终建议:
- 首选
requests:超过 90% 的情况下,你都会用到它,它是 Python Web 开发的必备技能。 - 明确服务类型:在调用前,务必确认目标 WebService 是 REST 还是 SOAP,查看其文档,寻找 URL 是
.../api/resource(REST) 还是...?wsdl(SOAP)。 - 仔细阅读文档:每个 API 都有其特定的规则,包括认证方式、请求/响应格式、参数名称等,官方文档是最好的参考资料。
