我可以在Python 2.6.5中使用unllode-ready替换urllib.quote和urllib.unquote吗?

Ken*_*der 41 python unicode urllib

Python urllib.quote并且urllib.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'
Run Code Online (Sandbox Code Playgroud)

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

In [6]: print urllib.unquote(urllib.quote(u'Cataño'.encode('utf8')))
Cataño
Run Code Online (Sandbox Code Playgroud)

它被认为是一个bug并且有一个修复,但不适用于我的Python版本.

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

decode_url(encode_url(u'Cataño')) == u'Cataño'
Run Code Online (Sandbox Code Playgroud)

有什么建议?

bob*_*nce 42

Python的urllib.quote和urllib.unquote无法正确处理Unicode

urllib根本不处理Unicode.根据定义,URL不包含非ASCII字符.当你处理时,urllib你应该只使用字节字符串.如果您希望这些代表Unicode字符,则必须手动编码和解码它们.

IRI可以包含非ASCII字符,将它们编码为UTF-8序列,但此时Python并没有irilib.

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

In [6]: print urllib.unquote(urllib.quote(u'Cataño'.encode('utf8')))
Cataño
Run Code Online (Sandbox Code Playgroud)

啊,现在你在控制台中键入Unicode,并在控制台上执行print-Unicode.这通常是不可靠的,尤其是在Windows和IPython控制台的情况下.

使用反斜杠序列输入很长的路径,您可以更容易地看到该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'
Run Code Online (Sandbox Code Playgroud)


Joh*_*hin 5

""将值编码为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'
>>>
Run Code Online (Sandbox Code Playgroud)

为了比较:

>>> # 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'
>>>
Run Code Online (Sandbox Code Playgroud)