如何对Python中的URL参数进行百分比编码?


299

如果我做

url = "http://example.com?p=" + urllib.quote(query)
  1. 它不编码/%2F(破坏OAuth规范化)
  2. 它不处理Unicode(引发异常)

有没有更好的图书馆?


1
这些不是URL参数,仅供参考。你应该澄清一下。
Jamie Marshall

Answers:


390

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.quoteurllib.parse.quote


1
谢谢你们,两个人都很棒。urlencode只会在一个循环中多次调用quoteplus,这不是我的任务(oauth)的正确规范化。
Paul Tarjan

6
规范:rfc 2396将其定义为保留,reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","这是urllib.quote正在处理的内容。
杰夫·谢菲尔德

63
urllib.quoteurlib.parse.quote,因为Python3。
Hibou57 2015年

5
urllib.parse.quote docs
Andreas Haferburg

此外,在编码搜索查询的情况下,你也许最好使用quote_plus: docs.python.org/3/library/... 1.编码默认2.斜线它还编码空间
帕维尔Vergeev

173

在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
这个名称quote在全球范围内相当模糊。使用urlencode:可能更好from urllib.parse import quote as urlencode
卢克,

请注意,已经有一个名为urlencodein 的函数urllib.parse执行完全不同的操作,因此最好选择其他名称,否则可能会严重混淆将来的代码阅读者。
jaymmer-恢复莫妮卡

48

我的答案类似于保罗的答案。

我认为模块requests要好得多。它基于urllib3。您可以尝试以下方法:

>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'

5
requests.utils.quote是python的链接quote。请参阅请求来源
Cjkjvfnby

16
requests.utils.quote是适用urllib.quote于python 2和urllib.parse.quotepython 3 的精简兼容性包装程序
Jeff Sheffield

13

如果您使用的是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)

2

最好在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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.