小ネタ: urllibでURLをパースする・生成する

urllibを使ったURLのパースと生成についてまとめます。よく使うのに、そのたびに調べてしまっているので。

パースする

まずはURLをパースする方法ですが、urllib.parse.urlparseにURL文字列を渡すだけです。
あとは、返されたParseResultオブジェクトから必要な情報 (ホスト名, パス, クエリパラメータ, フラグメント) を取得します。

from urllib.parse import urlparse

u = 'https://ohke.hateblo.jp/archive/category/Python?page=2&q=pandas#1'

result = urlparse(u)
print(result)
# ParseResult(scheme='https', netloc='ohke.hateblo.jp', path='/archive/category/Python', params='', query='page=2&q=pandas', fragment='1')
print(result.hostname, result.path, result.query, result.fragment)
# ohke.hateblo.jp /archive/category/Python page=2&q=pandas 1

デコードする

URLエンコードされていてそれをパース前にデコードしたい場合は、urllib.parse.unquoteでデコードしてしまいます。

from urllib.parse import unquote

u = 'https://ohke.hateblo.jp/archive/category/%e3%82%af%e3%83%ad%e3%83%bc%e3%83%a9?page=2&q=%e3%81%91%e6%97%a5%e8%a8%98#1'

decoded = unquote(u)
print(decoded)
# https://ohke.hateblo.jp/archive/category/クローラ?page=2&q=け日記#1

クエリパラメータを辞書にする

クエリパラメータはurllib.parse.parse_qsで辞書に変換できるので、さらに扱いやすくできます。

from urllib.parse import parse_qs

query_dict = parse_qs(result.query)
print(query_dict)
# {'page': ['2'], 'q': ['pandas']}

生成する

URLを生成する場合は、urllib.parse.urlparseに各パーツを渡せばOKです。

from urllib.parse import urlunparse

u = urlunparse((
    'https', 
    'ohke.hateblo.jp', 
    '/archive/category/Python', 
    None, 
    'page=2&q=pandas', 
    '1'
))
print(u)
# https://ohke.hateblo.jp/archive/category/Python?page=2&q=pandas#1