gpt4 book ai didi

python - 脚本在通过 REST 接口(interface)传递 Unicode 时遇到问题

转载 作者:行者123 更新时间:2023-12-01 06:10:45 25 4
gpt4 key购买 nike

我在让 Python 脚本通过 RESTful http 调用获取 Unicode 数据时遇到问题。

我有一个脚本,它使用 REST 接口(interface)从网站 X 读取数据,然后使用其 REST 接口(interface)将其推送到网站 Y。这两个系统都是开源的,并在我们的服务器上运行。站点 X 使用 PHP、Apache 和 PostgreSQL。站点 Y 是 Java、Tomcat 和 PostgreSQL。执行处理的脚本当前使用 Python。

总的来说,该脚本运行得很好。我们确实有一些国际用户,当尝试处理名称中包含 unicode 字符的用户时,事情就会崩溃。脚本的原始版本将 JSON 数据读取到 Python 中。数据自动转换为 Unicode。我很确定到目前为止一切都运行良好。为了输出数据,我使用 subprocess.Popen() 调用curl。这适用于常规 ascii,但 unicode 在传输过程中的某个地方被破坏了。我没有在任何地方收到错误,但是当在站点 B 上查看结果时,它不再被正确编码。

我知道这些字段支持 Unicode,因为我可以使用 Firefox 制作一个请求,将数据正确添加到站点 B。

下一个想法是不使用curl,而是在Python 中完成所有操作。我尝试将手工构建的 Unicode 字符串传递给 Python 的 urllib 来进行 REST 调用,但我收到了来自 urllib.urlopen() 的错误:UnicodeEncodeError:“ascii”编解码器无法对位置 103-105 中的字符进行编码:序号不在范围(128)

关于如何实现这项工作有什么想法吗?我不想重写太多,但如果有另一种更适合的脚本语言,我也不介意听到它。

这是我的 Python 测试脚本:

import urllibuni = u"abc_\u03a0\u03a3\u03a9"post = u"xdat%3Auser.login=unitest&"post += u"xdat%3Auser.primary_password=nauihe4r93nf83jshhd83&"post += u"xdat%3Auser.firstname=" + uni + "&"post += u"xdat%3Auser.lastname=" + uni ;url = u"http://localhost:8081/xnat/app/action/XDATRegisterUser"data = urllib.urlopen(url,post).read()

最佳答案

关于您的测试脚本,它失败了,因为您将 unicode 对象传递给 urllib.urlencode() (它是由 urlopen() 为您调用的)。它不支持 unicode 对象,因此它使用默认字符集 ascii 隐式编码。显然,它失败了。

处理 POSTing unicode 对象的最简单方法是显式的;收集数据并构建一个字典,使用适当的字符集对 unicode 值进行编码,对字典进行 urlencode(以获取 POSTable ascii 字符串),然后启动请求。您的示例可以重写为:

import urllib
import urllib2

## Build our post data dict
data = {
'xdat:user.login' : u'unitest',
'xdat:primary_password' : u'nauihe4r93nf83jshhd83',
'xdat:firstname' : u"abc_\u03a0\u03a3\u03a9",
'xdat:lastname' : u"abc_\u03a0\u03a3\u03a9",
}

## Encode the unicode using an appropriate charset
data = dict([(key, value.encode('utf8')) for key, value in data.iteritems()])

## Urlencode it for POSTing
data = urllib.urlencode(data)

## Build a POST request, get the response
url = "http://localhost:8081/xnat/app/action/XDATRegisterUser"
request = urllib2.Request(url, data)
response = urllib2.urlopen(request)

编辑:更一般地说,当您使用 python 发出 http 请求时(例如 urllib2.urlopen),响应的内容为您解码为 un​​icode。这意味着您需要了解发送它的服务器使用的编码。查看 content-type header ;通常它包含一个 charset=xyz

尽早对输入进行解码,并尽可能晚地对输出进行编码始终是谨慎的做法。

关于python - 脚本在通过 REST 接口(interface)传递 Unicode 时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6112226/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com