问题:如何对Python中的URL参数进行百分比编码?
如果我做
url = "http://example.com?p=" + urllib.quote(query)
- 它不编码
/
为%2F
(破坏OAuth规范化) - 它不处理Unicode(引发异常)
有没有更好的图书馆?
回答 0
Python 2
从文档:
urllib.quote(string[, safe])
使用%xx转义符替换字符串中的特殊字符。字母,数字和字符“ _.-”都不会被引用。默认情况下,此函数用于引用URL的路径部分。可选的safe参数指定不应引用的其他字符- 其默认值为’/’
这意味着通过“安全”将解决您的第一个问题:
>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'
关于第二个问题,有关于它的bug报告在这里。显然,它已在python 3中修复。您可以通过编码为utf8来解决此问题,如下所示:
>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller
顺便看看urlencode
Python 3
相同的,除了更换urllib.quote
用urllib.parse.quote
。
回答 1
在Python 3中,urllib.quote
已移至,urllib.parse.quote
并且默认情况下确实处理unicode。
>>> from urllib.parse import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
>>> quote('/El Niño/')
'/El%20Ni%C3%B1o/'
回答 2
我的答案类似于保罗的答案。
我认为模块requests
要好得多。它基于urllib3
。您可以尝试以下方法:
>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
回答 3
如果您使用的是django,则可以使用urlquote:
>>> from django.utils.http import urlquote
>>> urlquote(u"Müller")
u'M%C3%BCller'
请注意,自发布此答案以来对Python的更改意味着它现在是旧版包装器。从django.utils.http的Django 2.1源代码中:
A legacy compatibility wrapper to Python's urllib.parse.quote() function.
(was used for unicode handling on Python 2)
回答 4
最好在urlencode
这里使用。单个参数没有太大区别,但是恕我直言使代码更清晰。(看一个函数看起来很混乱quote_plus
!尤其是那些来自其他语言的函数)
In [21]: query='lskdfj/sdfkjdf/ksdfj skfj'
In [22]: val=34
In [23]: from urllib.parse import urlencode
In [24]: encoded = urlencode(dict(p=query,val=val))
In [25]: print(f"http://example.com?{encoded}")
http://example.com?p=lskdfj%2Fsdfkjdf%2Fksdfj+skfj&val=34
文件
urlencode:https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode
quote_plus:https ://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus