web-dev-qa-db-ja.com

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

私が行った場合

url = "http://example.com?p=" + urllib.quote(query)
  1. /%2Fにエンコードしません(OAuth正規化を破ります)
  2. Unicodeを処理しません(例外をスローします)

もっと良い図書館はありますか?

262
Paul Tarjan

から docs

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

ちなみに rlencode を見てみましょう

Python 3ではurllib.quoteurllib.parse.quoteに移動したことに注意してください

354
Nadia Alramli

Python 3では、 urllib.quoteurllib.parse.quote に移動し、デフォルトでUnicodeを処理します。

>>> from urllib.parse import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
>>> quote('/El Niño/')
'/El%20Ni%C3%B1o/'
152
Paolo Moretti

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

私はモジュールrequestsがはるかに良いと思います。それはurllib3に基づいています。これを試すことができます:

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

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)
10
Rick Westera

ここではurlencodeを使用することをお勧めします。 1つのパラメータに大きな違いはありませんが、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

1
balki