如何修复使用Python Suds调用网络服务时的unicode问题

7 投票
3 回答
8847 浏览
提问于 2025-04-16 10:02

我正在尝试使用Commission Junction(CJ)那些糟糕的网络服务。我可以让客户端连接并从CJ获取信息,但他们的数据库似乎包含了一些奇怪的字符,这导致出现了UnicideDecodeError的错误。

现在我正在做的是:

from suds.client import Client
wsdlLink = 'https://link-search.api.cj.com/wsdl/version2/linkSearchServiceV2.wsdl'
client = Client(wsdlLink)
result = client.service.searchLinks(developerKey='XXX', websiteId='XXX', promotionType='coupon')

这在大多数情况下都能正常工作,但当我遇到像“CorpNet® 10% Off Any Service”这样的记录时,那个®符号就会导致程序崩溃,然后我就会看到

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 758: ordinal not in range(128)" error.

有没有办法在我这边对®进行编码,这样在SUDS读取结果时就不会出错呢?

更新:为了更清楚地说明,那个®符号是来自CJ数据库的,出现在他们的响应中。所以我需要在SUDS处理响应之前,先解码那些非ASCII字符。我不太确定在SUDS中该怎么做(或者是否可以做到)。

3 个回答

0

我正在使用SUDS通过SOAP API与Salesforce进行连接。之前我遇到了同样的问题,直到我按照@J.F.Sabastian的建议,不再混用字符串和Unicode字符串类型。比如,像下面这样的SOQL字符串在SUDS 0.3.9中是可以正常工作的:

qstr = u"select Id, FirstName, LastName from Contact where FirstName='%s' and LastName='%s'"  % (u'Jorge', u'López')

我发现也不需要使用str.decode("utf-8")。

如果你是在Eclipse的PyDev中运行你的脚本,建议你去项目设置中,选择“项目” => “属性”,然后在“资源”下,把“文本文件编码”设置为UTF-8。在我的Mac上,默认是“MacRoman”。我想在Windows上,默认可能是Cp1252或ISO-8859-1(拉丁文)。你也可以在工作区设置这个,这样你的项目就会继承这个设置。这只会影响程序的源代码。

1

“注册商标”这个字符的编码是 U+00AE,在 UTF-8 中表示为 "\xc2\xae"。看起来你有一个用 UTF-8 编码的字符串对象,但某段代码(可能是默认设置)在执行 your_str_object.decode("ascii"),这会导致你看到的错误信息。

你需要做的是给我们一个完整的例子(也就是导致错误的所有代码),还有完整的错误信息和追踪记录,这样我们才能猜测问题出在你的代码里还是在引入的代码里。

3

隐式的Unicode解码错误是你在尝试把字符串(str)和Unicode对象相加时可能遇到的问题。Python会试图把字符串解码成Unicode,但它使用的是ASCII编码。如果你的字符串里有任何不是ASCII的内容,就会出现这个错误。

解决这个问题的方法是手动解码,像这样:

thestring = thestring.decode('utf8')

尽量在你从任何模块(在这个例子中是suds)接收到字符串后,立即解码任何可能包含非ASCII字符的字符串。

然后,如果suds不能处理Unicode(这可能会发生),确保在把文本交回给suds(或者任何其他会因为接收到Unicode而出错的库)之前,把它重新编码。

这样应该能很好地解决问题。虽然这可能是个大变化,因为你需要把所有内部处理从字符串转换为Unicode,但这样做是值得的。:)

撰写回答