Python

【Python】URLからクエリを取得する

GETリクエストをする場合、URLにqueryの情報が含まれている。

URLに含まれるqueryを辞書やリスト形式で取得する方法を説明する。

  1. URLをデコードする(必要に応じて)
  2. URLをparseする
  3. parseしたURLのqueryを利用しやすい形(辞書やリスト)にする

URLをデコードする

URLのうち、英数字以外の文字は「%20」のような文字で表示されていることがある(エンコードされた状態)。

queryの内容を正しく知るために、「%20」のような文字を正しい文字に置き換える(デコード)

from urllib.parse import quote, unquote

encode_url = "https%3A//www.sample.com/index%3Fq1%3D111%26q2%3D222%26q3%3Da%20b%20c"
decode_url = unquote(encode_url)
print(decode_url)
'https://www.sample.com/index?q1=111&q2=222&q3=a b c'

urllib.parseのunquoteでエンコードされたURLをデコードできる。(「%20」などを正しい文字に変換できる)

なお、URLをエンコードしたい場合はquoteを使う。

from urllib.parse import quote, unquote

sample_url = 'https://www.sample.com/index?q1=111&q2=222&q3=a b c'
encode_url = quote(sample_url)
print(encode_url)
'https%3A//www.sample.com/index%3Fq1%3D111%26q2%3D222%26q3%3Da%20b%20c'

URLをparseする

URLをparseして、scheme, netloc, path, params, query, fragmentに分解する。

from urllib.parse import urlparse, urlunparse

sample_url = "https://www.sample.com/index?q1=111&q2=222&q3=a b c"
parse_result = urlparse(sample_url)

# scheme, netloc, path, params, query, fragmentをキーとして持つnamed tupleが返ってくる
print(f"{parse_result}")
# schemeやqueryを取得
print(f"{parse_result.scheme=}")
print(f"{parse_result.query=}")
ParseResult(scheme='https', netloc='www.sample.com', path='/index', params='', query='q1=111&q2=222&q3=a b c', fragment='')
parse_result.scheme='https'
parse_result.query='q1=111&q2=222&q3=a b c'

urlparseでURLをparseできる。

scheme, netloc, path, params, query, fragmentを持つNamed Tupleが返ってくる。

queryを辞書やリストにする

parseしたURLのquery部分を利用しやすいように、辞書やリストにする。

クエリ―を辞書にする

from urllib.parse import urlparse

sample_url = "https://www.sample.com/index?q1=111&q2=222&q3=a b c"
parse_result = urlparse(sample_url)

# queryを&で分割。更に=で分割。変数名をキー、値を値として辞書にする
queries = dict([q.split("=") for q in parse_result.query.split("&")])
print(queries)
print(f"{queries.keys()=}")
print(f"{queries.values()=}")
print(f"{queries.items()=}")
{'q1': '111', 'q2': '222', 'q3': 'a b c'}
queries.keys()=dict_keys(['q1', 'q2', 'q3'])
queries.values()=dict_values(['111', '222', 'a b c'])
queries.items()=dict_items([('q1', '111'), ('q2', '222'), ('q3', 'a b c')])

queryは変数名と値が=でつながっており、複数の変数がある場合、各変数が&でつながっている。

なので、まずは&で分割し、その後=で分割することで変数名と値に分けられる。

クエリ―をリストにする

from urllib.parse import urlparse

sample_url = "https://www.sample.com/index?q1=111&q2=222&q3=a b c"
parse_result = urlparse(sample_url)

# queryを&で分割。更に=で分割。
queries = [{q.split("=")[0]: q.split("=")} for q in parse_result.query.split("&")]
print(queries)
print(f"{queries[0]=}")
[{'q1': '111'}, {'q2': '222'}, {'q3': 'a b c'}]
queries[0]={'q1': '111'}

分割方法は辞書と同じ。

最終的にどのように保持するかの問題なので、利用方法に合わせて保持すると良い。

まとめ

from urllib.parse import urlparse, unquote

sample_url = 'https%3A//www.sample.com/index%3Fq1%3D111%26q2%3D222%26q3%3Da%20b%20c'
decode_url = unquote(sample_url)

parse_result = urlparse(decode_url)
queries = [{q.split("=")[0]: q.split("=")} for q in parse_result.query.split("&")]

デコードしてパースしてクエリ―を分割して利用しやすい形にする。