Python urlencode 特殊字符
Python urlencode special character
我这里有这个变量
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 中被错误地 "represented"。
我该如何解决这个问题?
你 "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
,要么采用系统默认编码,根据你的 post,你将其设置为 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
urllib
和 urlparse
似乎与 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代码点。
我这里有这个变量
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 中被错误地 "represented"。
我该如何解决这个问题?
你 "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
,要么采用系统默认编码,根据你的 post,你将其设置为 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
urllib
和 urlparse
似乎与 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代码点。