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

如果我这样做

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

有更好的图书馆吗?

336683 次浏览

Python 2

的文档:

urllib.quote(string[, safe])

替换字符串中的特殊字符 使用%xx转义。字母,数字 以及字符的_。-从来没有 引用。缺省情况下,该函数为 用于引用路径部分 URL的。可选的安全参数 指定附加字符 不应该加引号- 它的默认值 值为'/'

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

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

关于第二个问题,有关于它的错误报告。显然它在Python 3中被修复了。你可以通过像这样编码utf - 8来解决它:

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

顺便说一下,看看urlencode

Python 3

在Python 3中,函数quote已被移动到urllib.parse:

>>> import urllib.parse
>>> print(urllib.parse.quote("Müller".encode('utf8')))
M%C3%BCller
>>> print(urllib.parse.unquote("M%C3%BCller"))
Müller

在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/'

我认为模块requests更好。它基于urllib3

你可以试试这个:

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

我的答案类似于

如果你正在使用Django,你可以使用urlquote:

>>> from django.utils.http import urlquote
>>> urlquote(u"Müller")
u'M%C3%BCller'

注意,对Python的更改意味着它现在是一个遗留包装器。来自Django 2.1的django.utils.http源代码:

A legacy compatibility wrapper to Python's urllib.parse.quote() function.
(was used for unicode handling on Python 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

文档

使用卷起的另一个方法:

import furl


url = "https://httpbin.org/get?hello,world"
print(url)
url = furl.furl(url).url
print(url)

输出:

https://httpbin.org/get?hello,world
https://httpbin.org/get?hello%2Cworld