Python 请求 POST 方法始终将 XML 解析为 ANSI

问题描述 投票:0回答:3

我有一个脚本,它使用 python 请求模块在 POST 方法中将 XML 发送到 API。 当我将脚本部署到我的 PROD 服务器 (Debian) 时,此代码在我的测试机器 (Windows) 上运行,我总是收到解析错误。 如果我将文件的编码更改为 ANSI,它将在 Debian 服务器上运行。

这似乎是某种编码问题。然而,从我的角度来看,我正确设置了所有内容,以便将文件作为 utf-8 发送。

这是相关的代码片段:

# prepare XML for API call
    url = "https://myurl.com/api/method"
    # use XML template and replace some wildcards
    payloadTemplate = open("message.xml", encoding="utf-8")
    payload = payloadTemplate.read()
    payload = str(payload % (sessiontoken, accountName, key, userId))
    headers = {
        'X-XYZ-API-COMPATIBILITY-LEVEL': '1234',
        'X-XYZ-API-CALL-NAME': 'methodname',
        'X-XYZ-API-SITEID': '11',
        'Content-Type': 'application/xml; charset=utf-8'
    }
    # send request
    response = requests.request("POST", url, headers=headers, data=payload)

XML 如下所示:

<?xml version="1.0" encoding="utf-8"?>
<APIMethod xmlns="urn:Tool:apis:eBLBaseComponents">
<RequesterCredentials>
<ToolAuthToken>%s</ToolAuthToken>
</RequesterCredentials>
<ItemID>12345678</ItemID>
<MemberMessage>
<Subject>Thanks</Subject>
<Body>random text some information %s another information %s</Body>
<QuestionType>General</QuestionType>
<RecipientID>%s</RecipientID>
</MemberMessage>
</APIMethod>

在 Windows 上使用 Postman 或脚本运行良好。在 Debian 上它不再工作了。如果我以 ANSI 编码保存 XML 文件,它也可以在 Debian 上运行。 我使用这个作为解决方法,不幸的是我希望对 Windows 和 Unix 有相同的解决方案(在我的例子中是 TEST 和 PROD)。我还想添加正确的德语字母。

很高兴获得任何帮助

我将 charset=utf-8 添加到标题中。它对 Debian 方面没有任何改变。在 Windows 中它仍然有效。当我将有效负载打印为字符串时,一切都很好。似乎没有编码问题。

python xml encoding python-requests debian
3个回答
0
投票

检查 Debian 系统的区域设置。

验证您已安装并设置正确的区域设置。

对于当前设置:

locale

已配置:

grep -v "^#" /etc/locale.gen

如果缺少相关区域设置,请编辑文件

/etc/locale.gen
并通过删除其行中的
#
标记来激活所需的条目。

即使配置正确,也请发出

sudo locale-gen

确保它们确实已生成。


0
投票

考虑使用 DOM 库(例如 Python 的内置

xml.etree
)解析有效负载 XML 模板,并使用库来更新元素文本。避免将 XML 视为文本文件,对整个内容进行
str
转换和格式化。对于文本的字符串格式,请使用当前推荐的 F 字符串标准:

import xml.etree.ElementTree as et
...

# handle default namespace
et.register_namespace('', "urn:Tool:apis:eBLBaseComponents")
nmsp = {"doc": "urn:Tool:apis:eBLBaseComponents"}

# parse XML template and replace element text
msg = et.parse("XMLAPIPayload.xml")

msg.find(".//doc:RequesterCredentials/doc:ToolAuthToken", namespaces = nmsp).text = sessiontoken
msg.find(".//doc:MemberMessage/doc:Body", namespaces = nmsp).text = (
    f"random text some information {accountName} another information {key}"
)
msg.find(".//doc:MemberMessage/doc:RecipientID", namespaces = nmsp).text = userId

# export to byte string
payload = et.tostring(msg.getroot(), encoding="utf-8")

# prepare XML for API call
url = "https://myurl.com/api/method"

headers = {
    'X-XYZ-API-COMPATIBILITY-LEVEL': '1234',
    'X-XYZ-API-CALL-NAME': 'methodname',
    'X-XYZ-API-SITEID': '11',
    'Content-Type': 'application/xml; charset=utf-8'
}

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

0
投票

全新安装 Debian 后,该问题不再存在。 Python 版本保持不变。因此,我假设(就像我一开始所做的那样)这是某种 Debian 引起的问题。

© www.soinside.com 2019 - 2024. All rights reserved.