是否有一个unicode就绪的替代品,我可以用于Python 2.6.5中的urllib.quote和urllib.unquote?

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 

它被认为是一个错误, 有一个修复 ,但不是我的版本的Python。

我想要的是类似于urllib.quote / urllib.unquote,但正确处理unicodevariables,这样的代码将工作:

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

任何build议?

Python的urllib.quote和urllib.unquote不能正确处理Unicode

urllib根本不处理Unicode。 根据定义,URL不包含非ASCII字符。 当你处理urllib你应该只使用字节string。 如果你想要那些代表Unicode字符,你将不得不手动编码和解码。

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

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

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

啊,现在你在input一个控制台inputUnicode,并print -Unicode到控制台。 这通常是不可靠的,尤其是在Windows和IPython控制台的情况下。

用反斜杠序列input很长的一段,你可以更容易地看到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' 

msgstr“”“将值编码为UTF8也不起作用”“”…你的代码的结果是一个str对象,它似乎是以UTF-8编码的input。 你需要解码或定义“不起作用” – 你期望什么?

注意:所以我们不需要猜测terminal的编码和数据的types,使用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' >>> 

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

 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') 

Python采用Unicode URL编码/解码

所以我有同样的问题:我想把查询参数在一个url,但其中一些包含奇怪的字符(变音符号)。

处理编码给了一个凌乱的url,是脆弱的。

我的解决scheme是将每个重音/奇怪的unicode字符replace为相同的ascii。 这是非常简单的感谢unidecode : 什么是删除Python unicodestring中的重音的最好方法是什么?

 pip install unidecode 

然后

 from unidecode import unidecode print unidecode(u"éèê") # prints eee 

所以我有一个干净的url。 也适用于中国等