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

Pau*_*jan 277 python url encoding urllib urlencode

如果我做

url = "http://example.com?p=" + urllib.quote(query)
Run Code Online (Sandbox Code Playgroud)
  1. 它不编码/%2F(休息OAuth的标准化)
  2. 它不处理Unicode(它抛出异常)

有更好的图书馆吗?

Nad*_*mli 368

来自文档:

urllib.quote(string[, safe])
Run Code Online (Sandbox Code Playgroud)

使用%xx转义替换字符串中的特殊字符.从不引用字母,数字和字符"_.-".默认情况下,此函数用于引用URL的路径部分.可选的safe参数指定不应引用的其他字符 - 其默认值为"/"

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

>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'
Run Code Online (Sandbox Code Playgroud)

关于第二个问题,有关于它的bug报告在这里.显然它是在python 3中修复的.您可以通过编码为utf8来解决它,如下所示:

>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller
Run Code Online (Sandbox Code Playgroud)

顺便看看urlencode

请注意,urllib.quote移到urllib.parse.quotePython3中

  • 自从Python3以来,`urllib.quote`被移动到`urlib.parse.quote`. (57认同)
  • 规范:[rfc 2396](https://www.ietf.org/rfc/rfc2396.txt)将这些定义为保留的`reserved =";" | "/"| "?" | ":"| "@"| "&"| "="| "+"| "$"| ","`urllib.quote正在处理的是什么. (6认同)
  • `urllib.parse.quote` [docs](https://docs.python.org/3/library/urllib.parse.html#url-quoting) (5认同)
  • @chrizonline 只需使用 `urllib.parse.quote(url, safe=':/')`。更好的是,对“某些路径”进行编码,然后连接字符串。这是Python,不是PHP。 (3认同)
  • 谢谢你,两个都很好。urlencode 只是在循环中多次调用quoteplus,这不是我的任务(oauth)的正确规范化。 (2认同)
  • 如果你想保留 http: 中的冒号,请执行 `urllib.parse.quote('http://example.com/some path/').replace('%3A', ':')` (2认同)

Pao*_*tti 163

在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/'
Run Code Online (Sandbox Code Playgroud)

  • “ quote”这个名字在全球范围内比较模糊。最好使用urlencode之类的东西:urllib.parse中的导入引用作为urlencode。 (2认同)
  • 请注意,“urllib.parse”中已经有一个名为“urlencode”的函数执行完全不同的操作,因此您最好选择另一个名称,否则可能会严重混淆代码的未来读者。 (2认同)

Ami*_*ini 43

我的回答类似于Paolo的回答.

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

>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
Run Code Online (Sandbox Code Playgroud)

  • `requests.utils.quote`是针对python 2的`urllib.quote`和针对python 3的`urllib.parse.quote`的瘦兼容性包装器 (14认同)
  • `requests.utils.quote`链接到python` quote`.请参阅[请求来源](https://github.com/kennethreitz/requests/blob/master/requests/compat.py#L36). (4认同)

Ric*_*era 13

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

>>> from django.utils.http import urlquote
>>> urlquote(u"Müller")
u'M%C3%BCller'
Run Code Online (Sandbox Code Playgroud)

请注意,自发布此答案以来对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)
Run Code Online (Sandbox Code Playgroud)


bal*_*lki 5

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
Run Code Online (Sandbox Code Playgroud)

文档