You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python将DataFrame转为SOAP Envelope格式SAP API Payload求助

解决DataFrame转SAP SOAP请求Payload的500错误问题

问题核心

你用df.to_xml()生成的XML不符合SAP SOAP服务要求的标准信封结构,SAP服务器无法解析,所以返回500错误。SOAP请求必须包含固定的<soap:Envelope>、<soap:Body>等外层节点,且内部数据结构要严格匹配WSDL定义的命名空间和字段格式。

解决方案步骤

1. 先明确SAP SOAP的请求结构

首先需要从WSDL中提取正确的请求格式:

  • 打开WSDL URL,找到目标操作的请求消息定义(比如<wsdl:message name="XXXRequest">)
  • 确认SOAP信封的命名空间(通常是http://schemas.xmlsoap.org/soap/envelope/,SAP可能还有自定义业务命名空间)
  • 记录请求体需要的根节点名称、字段层级关系

2. 方法一:用Zeep库自动生成符合要求的SOAP Payload

Zeep是Python专门处理SOAP的库,能自动解析WSDL并生成正确的请求结构,避免手动拼接XML的错误:

步骤:

  • 安装Zeep:

    pip install zeep
    
  • 改写代码:

    from zeep import Client
    from zeep.transports import Transport
    import requests
    import pandas as pd
    
    # 加载WSDL,生成客户端
    wsdl_url = "你的WSDL地址"
    # 配置证书
    session = requests.Session()
    session.cert = "certificate.pem"
    session.verify = False
    transport = Transport(session=session)
    client = Client(wsdl=wsdl_url, transport=transport)
    
    # 将DataFrame数据转换为WSDL要求的字典结构
    # 需严格匹配WSDL定义的字段名和层级,示例结构仅供参考
    df_data = df_xml_test.to_dict('records')
    request_payload = {
        "Material": df_data
    }
    
    # 调用SAP的目标操作(操作名从WSDL中获取,比如"CreateMaterial")
    response = client.service.CreateMaterial(**request_payload)
    
    # 查看响应
    print(response)
    

3. 方法二:手动构造SOAP Envelope(适合简单场景)

如果不想用Zeep,可以手动拼接符合格式的XML,示例如下(需替换为你的实际结构):

import requests
import pandas as pd

url = '你的SAP URL'
certificate_file = "certificate.pem"

# 从DataFrame提取数据,生成XML片段
df_xml_fragment = ""
for _, row in df_xml_test.iterrows():
    df_xml_fragment += f"""
    <Material>
        <Matnr>{row['matnr']}</Matnr>
        <Maktx>{row['maktx']}</Maktx>
        <!-- 其他字段按WSDL定义添加 -->
    </Material>
    """

# 拼接完整的SOAP Envelope
soap_envelope = f"""
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="你的SAP业务命名空间">
    <soap:Body>
        <ns:CreateMaterialRequest>
            {df_xml_fragment}
        </ns:CreateMaterialRequest>
    </soap:Body>
</soap:Envelope>
"""

# 发送请求
headers = {
    'Content-Type': 'application/soap+xml; charset=utf-8'
}

response = requests.post(url, headers=headers, data=soap_envelope,
                        cert=certificate_file, verify=False)

print(response.text)
print(response)

调试技巧

  • 查看response.text的详细错误信息,SAP通常会返回具体的格式错误(比如缺少命名空间、字段不匹配)
  • 用抓包工具对比你发送的Payload和SAP官方示例(如果有的话)的差异
  • 确认WSDL中的命名空间是否正确添加到Envelope和请求节点中

内容的提问来源于stack exchange,提问作者FarzadAvari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 21:21:47