Python urlencode特殊字符

时间:2017-04-11 09:24:48

标签: python unicode encoding python-2.x urlencode

我这里有这个变量

reload(sys)
sys.setdefaultencoding('utf8') 
foo = u'"Esp\xc3\xadrito"'

转换为“Espírito”。但是当我将我的变量传递给像这样的urlencode时

urllib.urlencode({"q": foo}) # q=%22Esp%C3%83%C2%ADrito%22'

特殊字符在URL中被“错误地表示”。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

"Espírito"的编码错误,我不知道你从哪里得到的,但这是正确的:

>>> s = u'"Espírito"'
>>> 
>>> s
u'"Esp\xedrito"'

然后对您的查询进行编码:

>>> u.urlencode({'q':s.encode('utf-8')})
'q=%22Esp%C3%ADrito%22'

这应该会为您提供正确的字符串编码。

编辑:这是关于您的查询字符串的正确编码,演示:

>>> s = u'"Espírito"'
>>> print s
"Espírito"
>>> s.encode('utf-8')
'"Esp\xc3\xadrito"'
>>> s.encode('latin-1')
'"Esp\xedrito"'
>>> 
>>> print "Esp\xc3\xadrito"
Espí­rito
>>> print "Esp\xedrito"
Espírito

这清楚地表明,您的字符串的正确编码是 latin-1(即使cp1252也适用),现在到目前为止据我了解,urlparse.parse_qs要么采用默认编码utf-8,要么采用您的系统默认编码,根据您的帖子,您也可以将其设置为utf-8

有趣的是,我正在你在评论中提供的查询,我得到了这个:

>>> q = "q=Esp%C3%ADrito"
>>> 
>>> p = urlparse.parse_qs(q)
>>> p['q'][0].decode('utf-8')
u'Esp\xedrito'
>>>
>>> p['q'][0].decode('latin-1')
u'Esp\xc3\xadrito'

#Clearly not ASCII encoding.
>>> p['q'][0].decode()

Traceback (most recent call last):
  File "<pyshell#320>", line 1, in <module>
    p['q'][0].decode()
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128)
>>> 
>>> p['q'][0]
'Esp\xc3\xadrito'
>>> print p['q'][0]
Espírito
>>> print p['q'][0].decode('utf-8')
Espírito

答案 1 :(得分:0)

urlliburlparse似乎与Python 2中的字节字符串一起使用。要获取unicode字符串,请使用utf-8进行编码和解码。

以下是往返的一个例子:

data = { 'q': u'Espírito'}

# to query string:
bdata = {k: v.encode('utf-8') for k, v in data.iteritems()}
qs = urllib.urlencode(bdata)

# qs = 'q=Esp%C3%ADrito'

# to dict:
bdata = urlparse.parse_qs(qs)
data = { k: map(lambda s: s.decode('utf-8'), v)
            for k, v in bdata.iteritems() }

# data = {'q': [u'Espídrito']}

注意转义序列的不同含义:在'Esp\xc3\xadrito'(字符串)中,它们表示字节,而在u'"Esp\xedrito"'(unicode对象)中,它们表示Unicode代码点。