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

时间:2009-11-08 02:43:45

标签: python url encoding urllib urlencode

如果我这样做

url = "http://example.com?p=" + urllib.quote(query)
  1. 它不会将/编码为%2F(中断OAuth规范化)
  2. 它不处理Unicode(它会引发异常)
  3. 有更好的图书馆吗?

5 个答案:

答案 0 :(得分:348)

来自docs

urllib.quote(string[, safe])
  

替换字符串中的特殊字符   使用%xx转义。字母,数字,   并且字符'_.-'永远不会   引。默认情况下,此功能是   用于引用路径部分   URL的可选安全参数   指定其他字符   不应引用 - 默认值   值为'/'

这意味着传递''为安全将解决您的第一个问题:

>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'

关于第二个问题,有一个关于它的错误报告here。显然它是在python 3中修复的。您可以通过编码为utf8来解决它:

>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller

顺便看看urlencode

注意 {3}在Python3中移至urllib.quote

答案 1 :(得分:151)

在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 :(得分:41)

我的回答与Paolo的答案相似。

我认为模块requests要好得多。它基于urllib3。 你可以试试这个:

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

答案 3 :(得分:10)

如果你正在使用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 :(得分:1)

最好在这里使用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