Python 2.6.5中的urllib.quote和urllib.unquote是否可以用unicode替代?

2024-04-26 05:18:39 发布

您现在位置:Python中文网/ 问答频道 /正文

Python的urllib.quoteurllib.unquote在Python 2.6.5中不能正确处理Unicode。这就是发生的情况:

In [5]: print urllib.unquote(urllib.quote(u'Cataño'))
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)

/home/kkinder/<ipython console> in <module>()

/usr/lib/python2.6/urllib.pyc in quote(s, safe)
   1222             safe_map[c] = (c in safe) and c or ('%%%02X' % i)
   1223         _safemaps[cachekey] = safe_map
-> 1224     res = map(safe_map.__getitem__, s)
   1225     return ''.join(res)
   1226 

KeyError: u'\xc3'

将值编码为UTF8也不起作用:

In [6]: print urllib.unquote(urllib.quote(u'Cataño'.encode('utf8')))
Cataño

它被认为是一个bug和there is a fix,但不是我的Python版本。

我想要的是类似于urllib.quote/urllib.unquote的东西,但是正确地处理unicode变量,这样这段代码就可以工作了:

decode_url(encode_url(u'Cataño')) == u'Cataño'

有什么建议吗?


Tags: inurlmapunicoderesurllibencodesafe
3条回答

我遇到了同样的问题,并使用了一个helper函数来处理非ascii和urllib.urlencode函数(包括引号和unquote):

def utf8_urlencode(params):
    import urllib as u
    # problem: u.urlencode(params.items()) is not unicode-safe. Must encode all params strings as utf8 first.
    # UTF-8 encodes all the keys and values in params dictionary
    for k,v in params.items():
        # TRY urllib.unquote_plus(artist.encode('utf-8')).decode('utf-8')
        if type(v) in (int, long, float):
            params[k] = v
        else:
            try:
                params[k.encode('utf-8')] = v.encode('utf-8')
            except Exception as e:
                logging.warning( '**ERROR utf8_urlencode ERROR** %s' % e )
    return u.urlencode(params.items()).decode('utf-8')

采用自Unicode URL encode / decode with Python

Python's urllib.quote and urllib.unquote do not handle Unicode correctly

urllib根本不处理Unicode。根据定义,url不包含非ASCII字符。在处理urllib时,应该只使用字节字符串。如果你想让这些字符代表Unicode字符,你将不得不手工编码和解码它们。

IRIs可以包含非ASCII字符,将它们编码为UTF-8序列,但是Python在这一点上没有irilib

Encoding the value to UTF8 also does not work:

In [6]: print urllib.unquote(urllib.quote(u'Cataño'.encode('utf8')))
Cataño

啊,好了,现在您在控制台中键入Unicode,并在控制台中执行print-Unicode。这通常是不可靠的,特别是在Windows和您的情况下with the IPython console

用反斜杠序列长距离地键入它,您可以更容易地看到urllib位确实起作用:

>>> u'Cata\u00F1o'.encode('utf-8')
'Cata\xC3\xB1o'
>>> urllib.quote(_)
'Cata%C3%B1o'

>>> urllib.unquote(_)
'Cata\xC3\xB1o'
>>> _.decode('utf-8')
u'Cata\xF1o'

“将值编码为UTF8也不起作用”。。。代码的结果是一个str对象,据猜测它似乎是用UTF-8编码的输入。你需要解码它或者定义“不工作”——你期望什么?

注意:为了不需要猜测终端的编码和数据类型,请使用print repr(whatever),而不是print whatever

>>> # Python 2.6.6
... from urllib import quote, unquote
>>> s = u"Cata\xf1o"
>>> q = quote(s.encode('utf8'))
>>> u = unquote(q).decode('utf8')
>>> for x in (s, q, u):
...     print repr(x)
...
u'Cata\xf1o'
'Cata%C3%B1o'
u'Cata\xf1o'
>>>

供比较:

>>> # Python 3.2
... from urllib.parse import quote, unquote
>>> s = "Cata\xf1o"
>>> q = quote(s)
>>> u = unquote(q)
>>> for x in (s, q, u):
...     print(ascii(x))
...
'Cata\xf1o'
'Cata%C3%B1o'
'Cata\xf1o'
>>>

相关问题 更多 >