[Python] urllib.parseによるURLエンコード/デコードの方法

Python スクレイピング モジュール

PythonでURLエンコードおよびデコードをするには、urllib.parseモジュールを使います。本記事ではこれらの使い方についてまとめます。

確認環境

  • OS: Ubuntu16.04LTS
  • Python3.7.1

URLエンコードとは

日本語や特殊文字などの非ASCII文字をクエリ文字列に組み込んでGETリクエストを送信する場合など、これらの文字をURL構成要素として使用できるよう適切にエンコードする必要があります。 これを一般的にURLエンコードと呼んでいます。

URLエンコードは、以下2つがあります。
※参考:パーセントエンコーディング- Wikipedia

URLエンコードを行う

urllib.parse.quote()関数によるURLエンコード

  • 特殊文字を%エスケープを使った文字に置き換えます。尚、”_.-~”は置き換えられません。
  • オプション引数safeはクオートしたくないASCII文字を指定できます。デフォルトは、”/”です
# アルファベット、数値、" _.-~ "および"/(safeのデフォルト値)"はクオートされない
>>> urllib.parse.quote('abc123_.-~/')
'abc123_.-~/'

# オプション引数safeを"*"に設定すると、"/"がクオートされ、"*"がクオートされなくなる
>>> urllib.parse.quote('abc123/*', safe="*")
'abc123%2F*'

# 日本語も%エンコードされます。
>>> urllib.parse.quote('お正月')
'%E3%81%8A%E6%AD%A3%E6%9C%88'

urllib.parse.quote_plus()関数によるURLエンコード

  • quote() と似ていますが、クエリ文字列を URL に挿入する時のために HTML フォームの値の空白をプラス記号「+」に置き換えます。
>>> urllib.parse.quote_plus('abc def')
'abc+def'
  • オリジナルの文字列に「+」がある場合は safe に指定されている場合を除きエンコードされます。
>>> urllib.parse.quote_plus('abc+def')
'abc%2Bdef'

# safeに"+"を指定した場合
>>> urllib.parse.quote_plus('abc+def', safe="+")
'abc+def'
  • safe にデフォルト値は設定されていません。
>>> urllib.parse.quote_plus('abc/def')
'abc%2Fdef'

URLエンコードされた値を元に戻す

urllib.parse.unquote()関数によるデコード

  • エスケープされた %xx をそれに対応した単一文字に置き換えます。
>>> urllib.parse.unquote('%E3%81%8A%E6%AD%A3%E6%9C%88')
'お正月'
>>> urllib.parse.unquote('abc%20def%2Aghi%21')
'abc def*ghi!'

urllib.parse.unquote_plus()関数によるデコード

  • unquote() と似ていますが、HTMLフォームの値のアンクオートのために「+」をスペースに置き換えます。
>>> urllib.parse.unquote_plus('abc+def')
'abc def'

クエリ文字列の生成

urllib.parse.urlencode()関数によるクエリ文字列生成

  • マッピング型オブジェクトまたは 2 個の要素からなるタプルのシーケンスを、パーセントエンコードされたASCII文字列に変換します。
  • 戻り値は、 ‘&’ 文字で区切られた key=value のペアからなる一組の文字列になります。
  • デフォルトで値をクオートはquote_plus() が使用されます。
    • つまり、スペースは ‘+’ 文字に、 ‘/’ 文字は%2Fにクォートされます。
    • ※ GETリクエストの標準に準拠 (application/x-www-form-urlencoded)。
# クエリ文字列の生成
>>> query = (('abc', '00'), ('def', '11'))
>>> urllib.parse.urlencode(query)
'abc=00&def=11'

# quote_plusによるエンコード
>>> query = (('ab c', '00'), ('de/f', '11'))
>>> urllib.parse.urlencode(query)
'ab+c=00&de%2Ff=11'

# 日本語も下記の通りエンコードされます
>>> query = (('天気', '00'), ('飛行機', '11'))
>>> urllib.parse.urlencode(query)
'%E5%A4%A9%E6%B0%97=00&%E9%A3%9B%E8%A1%8C%E6%A9%9F=11'

まとめ

urllib.parseモジュールを用いたURLエンコードの方法についてまとめました。
実際は例えばrequestsモジュール等が自動で処理をしてくれるので、実際にこれを使う場面は多くはないかもしれません。

Learn more...

書籍でもう少し詳しく学びたい場合はこちらもどうぞ。筆者もかなり参考にさせてもらっています!

シェアする
ひびきをフォローする
Hbk project