Python url encode / decode - 将%转义的十六进制数字转换为字符串

时间:2016-08-24 03:23:34

标签: python python-2.6 python-unicode

例如,如果我有一个编码字符串:

url='locality=Norwood&address=138+The+Parade&region=SA&country=AU&name=Pav%C3%A9+cafe&postalCode=5067'

name参数的字符为%C3%A9,实际上意味着字符é。

因此,我希望输出为:

new_url='locality=Norwood&address=138+The+Parade&region=SA&country=AU&name=Pavé+cafe&postalCode=5067'

我在 Python终端上尝试了以下步骤:

>>> import urllib2
>>> url='locality=Norwood&address=138+The+Parade&region=SA&country=AU&name=Pav%C3%A9+cafe&postalCode=5067'
>>> new_url=urllib2.unquote(url).decode('utf8')
>>> print new_url
locality=Norwood&address=138+The+Parade&region=SA&country=AU&name=Pavé+cafe&postalCode=5067
>>>

然而,当我在 Python脚本中尝试相同的事情并以myscript.py运行时,我得到以下堆栈跟踪:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 88: ordinal not in range(128)

我使用的是Python 2.6.6,由于工作原因无法切换到其他版本。

如何克服此错误?

非常感谢任何帮助。提前谢谢!

######################################################

修改

我意识到我得到了上述预期的输出。

但是,我想将new_url中的参数转换为字典,如下所示。这样做时,我无法在我的名字参数中保留特殊字符“é”。

print new_url
params_list = new_url.split("&")
print(params_list)
params_dict={}
for p in params_list:
   temp = p.split("=")
   params_dict[temp[0]] = temp[1]
print(params_dict)

输出:

NEW_URL

局部性=诺伍德&安培;地址= 138 + +的游行&安培;区域SA =&安培;国家= AU&安培;名称=密钉+咖啡&安培;邮编= 5067

params_list

[u'locality = Norwood',u'address = 138 + The + Parade',u'region = SA',u'country = AU',u'name = Pav \ xe9 + cafe',u'postalCode = 5067' ]

params_dict

{u'name':u'Pav \ xe9 + cafe',u'locality':u'Norwood',u'country':u'AU',u'region':u'SA',u'地址':u'138 + The + Parade',u'postalCode':u'5067'}

基本上......这个名字现在是'Pav \ xe9 + cafe'而不是所需的'Pavé'。

我怎样才能在params_dict中保留相同的特殊字符?

1 个答案:

答案 0 :(得分:0)

这实际上是由于__repr____str__之间的差异。打印unicode字符串时,会使用__str__并导致您在打印é时看到的new_url。但是,在打印列表或字典时,会使用__repr__,对列表和字典中的每个对象使用__repr__。如果您单独打印这些项目,则可以根据需要进行打印。

# -*- coding: utf-8 -*-
new_url = u'name=Pavé+cafe&postalCode=5067'
print(new_url)  # name=Pavé+cafe&postalCode=5067

params_list = [s for s in new_url.split("&")]
print(params_list)  # [u'name=Pav\xe9+cafe', u'postalCode=5067']
print(params_list[0])  # name=Pavé+cafe
print(params_list[1])  # postalCode=5067

params_dict = {}
for p in params_list:
    temp = p.split("=")
    params_dict[temp[0]] = temp[1]
print(params_dict)  # {u'postalCode': u'5067', u'name': u'Pav\xe9+cafe'}
print(params_dict.values()[0])  # 5067
print(params_dict.values()[1])  # Pavé+cafe

打印列表和字典的一种方法是获取字符串表示,然后用unicode-escape解码它们:

print(str(params_list).decode('unicode-escape'))  # [u'name=Pavé+cafe', u'postalCode=5067']
print(str(params_dict).decode('unicode-escape'))  # {u'postalCode': u'5067', u'name': u'Pavé+cafe'}

注意:这只是Python 2中的一个问题.Python 3按照您的预期打印字符。此外,您可能希望查看urlparse以解析您的网址而不是手动执行此操作。

import urlparse
new_url = u'name=Pavé+cafe&postalCode=5067'
print dict(urlparse.parse_qsl(new_url))  # {u'postalCode': u'5067', u'name': u'Pav\xe9 cafe'}