Flask调用支付SOAP API时如何从返回的XML响应中提取字段值
解决方案
方法一:使用Python标准库解析(无需额外安装依赖)
推荐用该方法,不需要引入第三方包,兼容性更好。
注意:你当前定义payload时外层用了双引号,和XML内部的属性双引号冲突,会触发Python语法错误,建议把payload外层替换为三单引号包裹。
完整的请求+解析代码如下:
import requests import xml.etree.ElementTree as ET url = "https://sandbox.***.pt/****/api/api.php?wsdl=replica.*****.wsdl" # 外层用三单引号避免和内部双引号冲突 payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:api="API_Library"> <soapenv:Header/> <soapenv:Body> <api:gerarReferenciaMB> <valor>5</valor> <chave>****</chave> <id>1</id> <!--Optional:--> <admin_callback>0</admin_callback> <!--Optional:--> <token>0</token> <!--Zero or more repetitions:--> <campos_extra> <id>0</id> <valor>0</valor> </campos_extra> <!--Optional:--> <per_dup>0</per_dup> <!--Optional:--> <testa_pagamento>1</testa_pagamento> </api:gerarReferenciaMB> </soapenv:Body> </soapenv:Envelope>''' headers = { 'Content-Type': 'text/xml' } response = requests.request("POST", url, headers=headers, data=payload) # 新增解析逻辑 if response.status_code == 200: # 注册XML命名空间,和返回结果的命名空间对应 ns = { 'soapenv': 'http://schemas.xmlsoap.org/soap/envelope/', 'ns1': 'API_Library' } root = ET.fromstring(response.text) # 提取对应字段并赋值给变量 sucesso = root.find('.//ns1:gerarReferenciaMBResponse/sucesso', ns).text entidade = root.find('.//ns1:gerarReferenciaMBResponse/entidade', ns).text referencia = root.find('.//ns1:gerarReferenciaMBResponse/referencia', ns).text valor = int(root.find('.//ns1:gerarReferenciaMBResponse/valor', ns).text) estado = int(root.find('.//ns1:gerarReferenciaMBResponse/estado', ns).text) resposta = root.find('.//ns1:gerarReferenciaMBResponse/resposta', ns).text # 转换布尔值 sucesso = True if sucesso == 'true' else False
方法二:使用xmltodict转字典操作(更简单)
如果接受安装第三方依赖,可以用xmltodict直接把XML转成Python字典,无需手动处理命名空间路径:
- 先安装依赖:
pip install xmltodict - 解析代码:
import xmltodict if response.status_code == 200: resp_dict = xmltodict.parse(response.text) mb_resp = resp_dict['SOAP-ENV:Envelope']['SOAP-ENV:Body']['ns1:gerarReferenciaMBResponse'] # 直接从字典中取值即可 sucesso = True if mb_resp['sucesso'] == 'true' else False entidade = mb_resp['entidade'] referencia = mb_resp['referencia'] valor = int(mb_resp['valor']) estado = int(mb_resp['estado']) resposta = mb_resp['resposta']
注意事项
- 实际生产环境建议加
try-except捕获异常,处理接口返回格式异常、字段缺失等边界情况 - 调用支付接口前建议先校验请求参数的合法性,避免异常请求产生不必要的费用
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

