我有一个脚本,它使用 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 中它仍然有效。当我将有效负载打印为字符串时,一切都很好。似乎没有编码问题。
检查 Debian 系统的区域设置。
验证您已安装并设置正确的区域设置。
对于当前设置:
locale
已配置:
grep -v "^#" /etc/locale.gen
如果缺少相关区域设置,请编辑文件
/etc/locale.gen
并通过删除其行中的 #
标记来激活所需的条目。
即使配置正确,也请发出
sudo locale-gen
确保它们确实已生成。
考虑使用 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)
全新安装 Debian 后,该问题不再存在。 Python 版本保持不变。因此,我假设(就像我一开始所做的那样)这是某种 Debian 引起的问题。