今回は、Pythonのurllib.parseモジュールでURLの構成を解析する方法をご紹介します。
Pythonのurllib.parseモジュールを使うと、URLの各構成要素を手軽に解析・操作できます。
たとえば、URLのスキーム(scheme)やネットロケーション(netloc)などを分解したり、クエリ文字列(query)を一括で処理したりといった操作が可能です。
ここでは、代表的な関数の使い方や、よく利用する場面での注意点をまとめてご紹介します。
urllib.parseモジュールの概要
urllib.parseモジュールは、URLを解析して各パーツに分割したり、逆にパーツを組み合わせてURLを生成したりする機能を提供します。
URLは一般的に以下の要素で構成されています。
- scheme: http, https など
- netloc: ホスト名やポート番号(例: www.example.com:8080)
- path: リソースへアクセスするためのパス(例: /path/to/page)
- params: パスに付随する追加情報(セミコロン区切りで表現)
- query: クエリ文字列(例: query=python&lang=ja)
- fragment: ページ内の特定のセクション(例: section1)
これらの要素を自在に扱うことで、さまざまなURL操作が簡単に行えます。
主要な関数と具体的な使い方
ここでは、よく使われる関数をいくつか取り上げます。
1. urlparse関数
urlparseは、URLをscheme、netloc、path、params、query、fragmentに分解し、結果をParseResultという形式で返します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from urllib.parse import urlparse # 解析対象のURL url = "https://www.example.com:8080/path/to/page;params?query=python&lang=ja#section1" result = urlparse(url) print("Scheme:", result.scheme) # URLのスキーム print("Netloc:", result.netloc) # ホスト名やポート番号など print("Path:", result.path) # URLのパス print("Params:", result.params) # パスに付随するパラメータ print("Query:", result.query) # クエリ文字列 print("Fragment:", result.fragment) # フラグメント |
Scheme: https
Netloc: www.example.com:8080
Path: /path/to/page
Params: params
Query: query=python&lang=ja
Fragment: section1
params部分とpath部分が分けて取得できるのが特徴です。
2. urlsplit関数
urlsplitはurlparseに似ていますが、paramsを分割せずにpathと一緒に扱います。
1 2 3 4 5 6 7 8 9 10 |
from urllib.parse import urlsplit url = "https://www.example.com:8080/path/to/page;params?query=python&lang=ja#section1" result = urlsplit(url) print("Scheme:", result.scheme) print("Netloc:", result.netloc) print("Path:", result.path) print("Query:", result.query) print("Fragment:", result.fragment) |
Scheme: https
Netloc: www.example.com:8080
Path: /path/to/page;params
Query: query=python&lang=ja
Fragment: section1
パスにparamsが含まれるため、urlparseと使い分ける必要がある場面もあります。
3. クエリ文字列の解析: parse_qs と parse_qsl
parse_qsは、クエリ文字列を辞書に変換します。
1 2 3 4 5 6 |
from urllib.parse import parse_qs query = "query=python&lang=ja&lang=en" qs_dict = parse_qs(query) print("Dictionary:", qs_dict) |
Dictionary: {‘query’: [‘python’], ‘lang’: [‘ja’, ‘en’]}
langのように同一キーが複数含まれると、対応する値がリストで格納されるのが特徴です。
parse_qslは、クエリ文字列をキーと値のタプルのリストとして取得します。
1 2 3 4 5 6 |
from urllib.parse import parse_qsl query = "query=python&lang=ja&lang=en" qs_list = parse_qsl(query) print("List:", qs_list) |
List: [(‘query’, ‘python’), (‘lang’, ‘ja’), (‘lang’, ‘en’)]
辞書ではなく、順序を保持したリストが必要な場合に便利です。
4. URLの結合: urljoin
urljoinは、ベースURLと相対URLを組み合わせて絶対URLを生成します。
1 2 3 4 5 6 7 |
from urllib.parse import urljoin base = "https://www.example.com/path/to/" relative = "page.html" absolute = urljoin(base, relative) print("Absolute URL:", absolute) |
Absolute URL: https://www.example.com/path/to/page.html
ベースURLと相対パスを単純につなげるのではなく、正しい形に調整してくれます。
5. クエリ文字列の作成: urlencode
urlencodeは、辞書やシーケンスをクエリ文字列に変換します。
なお、スペースは+でエンコードされるのがデフォルトの挙動です。
1 2 3 4 5 6 |
from urllib.parse import urlencode params = {"query": "python urllib", "lang": "ja"} encoded_query = urlencode(params) print("Encoded query:", encoded_query) |
Encoded query: query=python+urllib&lang=ja
6. URLエンコード/デコード: quote と unquote
quoteは、URLで使用できない文字(日本語や特殊文字など)をエンコードします。
unquoteは、エンコード済みの文字列を元に戻します。
1 2 3 4 5 6 7 8 |
from urllib.parse import quote, unquote text = "こんにちは 世界" encoded_text = quote(text) decoded_text = unquote(encoded_text) print("Encoded:", encoded_text) print("Decoded:", decoded_text) |
Encoded: %E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%20%E4%B8%96%E7%95%8C
Decoded: こんにちは 世界
日本語を含むURLを扱う際には、適切なエンコード・デコードが重要です。
7. フラグメントの除去: urldefrag
urldefragは、URLからfragment(「#」以降)を除去し、除去後のURLとフラグメントを返します。
1 2 3 4 5 6 7 |
from urllib.parse import urldefrag url_with_fragment = "https://www.example.com/page.html#section1" url_without_fragment, frag = urldefrag(url_with_fragment) print("URL without fragment:", url_without_fragment) print("Fragment:", frag) |
URL without fragment: https://www.example.com/page.html
Fragment: section1
よくあるエラーや注意点
URL形式の例外や特殊ケースに対応するには、各関数がどのように動作するかを把握しておく必要があります。
urlparseとurlsplitの違いは特に混乱しやすいので、扱うURLの形式に合わせて選択してください。
parse_qsによる重複キーの扱いも重要です。
同一のキーを複数含むクエリ文字列を想定していないコードを書くと、意図しないリスト型の値が返ってきてエラーにつながる可能性があります。
特殊文字や日本語を含むURLではquoteとunquote、あるいはurlencodeの使い方を誤ると正しく通信できない場合があります。
稀にRFCに準拠していないURLを扱わなければならないケースもあり、そのような場合は事前に整形処理を行うなどの工夫が必要です。
まとめ
urllib.parseモジュールを活用すると、URLの構成要素を自在に分解・操作できます。
各関数の特徴を理解して、必要に応じて使い分けることがポイントです。
正しいエンコードやクエリ解析を行えば、さまざまなWebサービスと安全にデータをやり取りできます。