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

Glue Python脚本:SOAP API读取XML转Parquet存S3解析失败求助

解决Pandas read_xml解析SOAP XML返回NaN的问题

问题原因

SOAP返回的XML带有命名空间(如soap前缀),且目标数据嵌套在多层节点中,pd.read_xml()默认无法自动定位到深层的结果节点,导致解析后得到空值(NaN)。

解决方案一:利用已解析的xmltodict结果构造DataFrame(最简方案)

你已经通过xmltodict成功提取到了结果值,直接用这个值构造DataFrame即可,无需再用read_xml解析整个SOAP响应:

import requests
import xmltodict
import pandas as pd
import pyarrow

url = "https://www.w3schools.com/xml/tempconvert.asmx"

payload = """<?xml version="1.0" encoding="utf-8"?>
        <soap12:Envelope 
                xmlns:xsi="http://w3.org/2002/XMLSchema-instance"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:soap12="http://schemas.xmlsoap.org/soap/envelope/">
        <soap12:Body>
          <CelsiusToFahrenheit xmlns="https://www.w3schools.com/xml/">
          <Celsius>20</Celsius>
          </CelsiusToFahrenheit>
        </soap12:Body>
       </soap12:Envelope>"""
headers = {
    'Content-Type': 'text/xml; charset=utf-8'
}

response = requests.request("POST", url, headers=headers, data=payload)
# 用xmltodict提取结果
result_dict = xmltodict.parse(response.text)['soap:Envelope']['soap:Body']['CelsiusToFahrenheitResponse']
# 构造DataFrame
df = pd.DataFrame([result_dict])

s3_url = 's3://bucket/folder/bucket.parquet'
df.to_parquet(s3_url)

# 验证输出
print(df)

这个方案直接复用你已有的xmltodict解析逻辑,避免了read_xml的命名空间和节点定位问题,输出的DataFrame会包含CelsiusToFahrenheitResult列和对应的值。

解决方案二:配置read_xml的命名空间与XPath(如果坚持用read_xml)

如果必须使用pd.read_xml(),需要指定SOAP的命名空间,并通过XPath定位到目标节点:

import requests
import pandas as pd
import pyarrow

url = "https://www.w3schools.com/xml/tempconvert.asmx"

payload = """<?xml version="1.0" encoding="utf-8"?>
        <soap12:Envelope 
                xmlns:xsi="http://w3.org/2002/XMLSchema-instance"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:soap12="http://schemas.xmlsoap.org/soap/envelope/">
        <soap12:Body>
          <CelsiusToFahrenheit xmlns="https://www.w3schools.com/xml/">
          <Celsius>20</Celsius>
          </CelsiusToFahrenheit>
        </soap12:Body>
       </soap12:Envelope>"""
headers = {
    'Content-Type': 'text/xml; charset=utf-8'
}

response = requests.request("POST", url, headers=headers, data=payload)

# 定义命名空间:soap对应SOAP信封的命名空间,ws对应W3Schools的服务命名空间
namespaces = {
    "soap": "http://schemas.xmlsoap.org/soap/envelope/",
    "ws": "https://www.w3schools.com/xml/"
}

# 使用XPath定位到结果节点
df = pd.read_xml(
    response.text,
    xpath="//soap:Envelope/soap:Body/ws:CelsiusToFahrenheitResponse",
    namespaces=namespaces
)

s3_url = 's3://bucket/folder/bucket.parquet'
df.to_parquet(s3_url)

# 验证输出
print(df)

关键说明:

  • namespaces参数必须匹配XML中的命名空间前缀和URI,这里soap对应SOAP信封的命名空间,ws对应W3Schools服务的自定义命名空间。
  • xpath路径精准定位到包含结果的CelsiusToFahrenheitResponse节点,确保read_xml能正确提取数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:42:48