Python发送XML请求遇阻:数据填充与响应解析求助
解决Python发送XML请求的两个问题
问题1:XML模板变量填充失效
原因
你定义的XML字符串仅包含{amount}这类占位符,但未执行格式化操作,Python不会自动替换占位符,导致XML内容未填入变量值。另外模板里<code>标签的闭合标签是</Code>(大小写不一致),可能引发XML解析错误,需统一标签大小写。
解决方法
两种常用的变量填充方式:
- f-string(Python 3.6+支持):在字符串开头加
f,直接解析占位符 str.format()方法:传入变量名与对应值
修改后的XML模板示例
# 方式1:f-string xml = f'''<?xml version="1.0" encoding="utf-8"?> <API3G> <Code>4332-9D7F-4E09-96D4-3D44E7A83EA3</Code> <Transaction> <PaymentAmount>{amount}</PaymentAmount> <customerEmail>{email}</customerEmail> </Transaction> <Services> <Service> <ServiceDate>{datejson_str}</ServiceDate> </Service> </Services> </API3G>''' # 方式2:str.format() xml = '''<?xml version="1.0" encoding="utf-8"?> <API3G> <Code>4332-9D7F-4E09-96D4-3D44E7A83EA3</Code> <Transaction> <PaymentAmount>{amount}</PaymentAmount> <customerEmail>{email}</customerEmail> </Transaction> <Services> <Service> <ServiceDate>{datejson_str}</ServiceDate> </Service> </Services> </API3G>'''.format(amount=amount, email=email, datejson_str=datejson_str)
问题2:无法解析XML响应获取TransToken
原因
你收到的响应是XML格式,但代码中用response.json()解析,这会直接报错——XML并非JSON格式,必须用XML解析工具处理。
解决方法
使用Python内置的xml.etree.ElementTree模块解析XML响应,步骤如下:
- 从响应中获取XML文本内容
- 解析XML为Element对象
- 定位
TransToken标签并提取其文本值
修改后的响应处理代码
import xml.etree.ElementTree as ET # 发送请求后处理响应 response = requests.post(url, data=xml, headers=headers) # 解析XML响应 root = ET.fromstring(response.content) # 提取TransToken值 trans_token = root.find('TransToken').text # 拼接跳转URL cashier_response = f'https://secure.powerpay.com/p.php?ID={trans_token}' return HttpResponseRedirect(cashier_response)
完整修复后的代码
import json import datetime import xml.etree.ElementTree as ET from django.http import HttpResponseRedirect from django.shortcuts import render from .forms import FormPaymentForm # 导入你的表单类 def start_xml_payment(request): if request.method == 'POST': form = FormPaymentForm(request.POST) if form.is_valid(): payment = form.save() first_name = request.user.first_name last_name = request.user.last_name email = request.user.email serdate = datetime.datetime.now() ref = payment.ref amount = payment.amount fees = payment.fees datejson_str = json.dumps({'created_at': serdate}, default=str) url = 'https://secure.powerpay.com/API/v6/' # 使用f-string填充XML模板,修正标签大小写 xml = f'''<?xml version="1.0" encoding="utf-8"?> <API3G> <Code>4332-9D7F-4E09-96D4-3D44E7A83EA3</Code> <Transaction> <PaymentAmount>{amount}</PaymentAmount> <customerEmail>{email}</customerEmail> </Transaction> <Services> <Service> <ServiceDate>{datejson_str}</ServiceDate> </Service> </Services> </API3G>''' headers = {'Content-Type': 'application/xml'} response = requests.post(url, data=xml, headers=headers) # 解析XML响应获取TransToken root = ET.fromstring(response.content) trans_token = root.find('TransToken').text # 拼接跳转URL cashier_response = f'https://secure.powerpay.com/p.php?ID={trans_token}' return HttpResponseRedirect(cashier_response) else: # 修正GET请求时的表单初始化错误 form = FormPaymentForm() return render(request, 'dpo/start_dpo_payment.html', {'form': form})
额外提示:原代码中GET请求分支错误传入request.POST,已修正为FormPaymentForm(),避免初始化表单时出现异常。
内容的提问来源于stack exchange,提问作者Echiye Forcde
相关产品推荐
相关产品推荐

