PythonでURLパラメータをパーセントエンコードする方法は?


299

私が行った場合

url = "http://example.com?p=" + urllib.quote(query)
  1. それはコードしない/%2F(休憩OAuthの正規化)
  2. Unicodeを処理しません(例外をスローします)

より良いライブラリはありますか?


1
これらは参考までに、URLパラメータではありません。明確にする必要があります。
ジェイミーマーシャル

回答:


390

Python 2

ドキュメントから:

urllib.quote(string[, safe])

%xxエスケープを使用して、文字列内の特殊文字を置き換えます。文字、数字、および文字「_.-」は引用符で囲まれません。デフォルトでは、この関数はURLのパスセクションを引用することを目的としています。オプションのsafeパラメータは、引用符で囲まない追加の文字を指定しますデフォルト値は「/」です

安全のために ''を渡すと、最初の問題が解決します:

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

2番目の問題については、こちらにバグレポートがあります。どうやらそれは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.quotePython3以降、に移動しました。
Hibou57

5
urllib.parse.quote docs
Andreas Haferburg

また、検索クエリをエンコードする場合は、quote_plus:docs.python.org/3/library/…を使用した方がよいでしょう 。デフォルトではスラッシュをエンコードします。2。スペースもエンコードします
Pavel Vergeev

174

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
Luc

まったく別のことを行う関数urlencodeurllib.parseすでにinにあることに注意してください。そのため、別の名前を選択するか、コードの将来の読者を深刻に混乱させる危険を冒した方がよいでしょう。
jaymmer-モニカを

48

私の答えはパオロの答えに似ています。

モジュールの方requestsがずっといいと思います。に基づいていurllib3ます。あなたはこれを試すことができます:

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

5
requests.utils.quotepythonへのリンクquoteです。リクエストソースをご覧ください。
Cjkjvfnby 2015

16
requests.utils.quoteurllib.quotePython 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ここで使うほうがいいです。単一パラメーターの場合はそれほど違いはありませんが、IMHOはコードをより明確にします。(関数を見るのは混乱します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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.