在utf-8字符串上使用python的urllib.quote_plus和'safe'参数
我在Python代码中有一个unicode字符串:
name = u'Mayte_Martín'
我想把它用在SPARQL查询中,这意味着我需要用'utf-8'对这个字符串进行编码,并使用urllib.quote_plus或者requests.quote来处理它。不过,这两个quote函数的表现有点奇怪,尤其是当我使用和不使用'safe'参数时,差别很明显。
from urllib import quote_plus
没有'safe'参数的情况:
quote_plus(name.encode('utf-8'))
Output: 'Mayte_Mart%C3%ADn'
有'safe'参数的情况:
quote_plus(name.encode('utf-8'), safe=':/')
Output:
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
<ipython-input-164-556248391ee1> in <module>()
----> 1 quote_plus(v, safe=':/')
/usr/lib/python2.7/urllib.pyc in quote_plus(s, safe)
1273 s = quote(s, safe + ' ')
1274 return s.replace(' ', '+')
-> 1275 return quote(s, safe)
1276
1277 def urlencode(query, doseq=0):
/usr/lib/python2.7/urllib.pyc in quote(s, safe)
1264 safe = always_safe + safe
1265 _safe_quoters[cachekey] = (quoter, safe)
-> 1266 if not s.rstrip(safe):
1267 return s
1268 return ''.join(map(quoter, s))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)
问题似乎出在rstrip函数上。我尝试做了一些修改,并调用了...
quote_plus(name.encode('utf-8'), safe=u':/'.encode('utf-8'))
但这并没有解决问题。这里可能是什么原因呢?
3 个回答
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import urllib
name = u'Mayte_Martín'
print urllib.quote_plus(name.encode('utf-8'), safe=':/')
在我这边运行得很好(Python 2.7.9,Debian系统)
(我不知道答案,但因为声望的原因我不能发表评论)
7
根据这个错误报告,这里有一个解决办法:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from urllib import quote_plus
name = u'Mayte_Martín'
quote_plus(name.encode('utf-8'), safe=':/'.encode('utf-8'))
你必须把在quote
或quote_plus
方法中的两个参数都用utf-8
进行encode
处理。
14
我在回答我自己的问题,希望能帮助到遇到同样问题的人。
这个问题出现在你在当前工作环境中进行以下导入后,执行其他任何操作之前。
from __future__ import unicode_literals
这个导入不知怎么的和下面这段代码不兼容。
from urllib import quote_plus
name = u'Mayte_Martín'
quote_plus(name.encode('utf-8'), safe=':/')
如果不导入unicode_literals,下面的代码就能正常运行。