# 20.16. `urlparse` --- URL を解析して構成要素にする

注釈

`urlparse` モジュールは、Python 3 では `urllib.parse` にリネームされました。 2to3 ツールが自動的にソースコードの import を修正します。

ソースコード: Lib/urlparse.py

このモジュールでは URL (Uniform Resource Locator) 文字列をその構成要素 (アドレススキーム、ネットワーク上の位置、パスその他) に分解したり、構成要素を URL に組みなおしたり、"相対 URL (relative URL)" を指定した "基底 URL (base URL)" に基づいて絶対 URL に変換するための標準的なインタフェースを定義しています。

このモジュールは Relative Uniform Resource Locators (相対 URL) に関する RFC に適合するよう設計されていおり、次のスキームをサポートしています: `file`, `ftp`, `gopher`, `hdl`, `http`, `https`, `imap`, `mailto`, `mms`, `news`, `nntp`, `prospero`, `rsync`, `rtsp`, `rtspu`, `sftp`, `shttp`, `sip`, `sips`, `snews`, `svn`, `svn+ssh`, `telnet`, `wais`.

バージョン 2.5 で追加: `sftp` および `sips` スキームのサポートが追加されました。

`urlparse` モジュールは以下の関数を定義しています:

`urlparse.``urlparse`(urlstring[, scheme[, allow_fragments]])

  URL を解析して 6 つの構成要素にし、6 要素のタプルを返します。このタプルは URL の一般的な構造: `scheme://netloc/path;parameters?query#fragment` に対応しています。各タプル要素は文字列で、空の場合もあります。構成要素がさらに小さい要素に分解されることはありません (例えばネットワーク上の位置は単一の文字列になります)。また % によるエスケープは展開されません。上で示された区切り文字がタプルの各要素の一部分として含まれることはありませんが、path 要素の先頭のスラッシュがある場合には例外です。たとえば以下のようになります:

      >>> from urlparse import urlparse
      >>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
      >>> o   # doctest: +NORMALIZE_WHITESPACE
      ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
                  params='', query='', fragment='')
      >>> o.scheme
      'http'
      >>> o.port
      80
      >>> o.geturl()
      'http://www.cwi.nl:80/%7Eguido/Python.html'

  RFC 1808 にある文法仕様に基づき、urlparse は '//' で始まる場合にのみ netloc を認識します。それ以外の場合は、入力は相対URLであると推定され、path 部分で始まることになります。

      >>> from urlparse import urlparse
      >>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html')
      ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
                 params='', query='', fragment='')
      >>> urlparse('www.cwi.nl/%7Eguido/Python.html')
      ParseResult(scheme='', netloc='', path='www.cwi.nl/%7Eguido/Python.html',
                 params='', query='', fragment='')
      >>> urlparse('help/Python.html')
      ParseResult(scheme='', netloc='', path='help/Python.html', params='',
                 query='', fragment='')

  scheme 引数が指定されている場合、標準のアドレススキームを表し、アドレススキームを指定していない URL に対してのみ使用されます。この引数の標準の値は空文字列です。

  引数 allow_fragments が偽の場合、URL のアドレススキームがフラグメント指定をサポートしていても、フラグメント識別子はURLのそれ以前の部分に続く構成要素として認識、解析されません。この引数のデフォルトは `True` です。

  戻り値は実際には `tuple` のサブクラスのインスタンスです。このクラスには以下の読み出し専用の便利な属性が追加されています:

  属性 | インデックス | `値` | 指定されなかった場合の値
  --- | --- | --- | ---
  `scheme` | 0 | URL スキーム | scheme パラメータ
  `netloc` | 1 | ネットワーク上の位置 | 空文字列
  `path` | 2 | 階層的パス | 空文字列
  `params` | 3 | 最後のパス要素に対するパラメータ | 空文字列
  `query` | 4 | クエリ要素 | 空文字列
  `fragment` | 5 | フラグメント識別子 | 空文字列
  `username` |  | ユーザ名 | `None`
  `password` |  | パスワード | `None`
  `hostname` |  | ホスト名 (小文字) | `None`
  `port` |  | ポート番号を表わす整数 (もしあれば) | `None`

  結果オブジェクトのより詳しい情報は urlparse() および urlsplit() の結果 節を参照してください。

  バージョン 2.5 で変更: 戻り値に属性が追加されました。

  バージョン 2.7 で変更: IPv6 URL の解析も行えるようになりました。

`urlparse.``parse_qs`(qs[, keep_blank_values[, strict_parsing[, max_num_fields]]])

  文字列引数として渡されたクエリ文字列 (application/x-www-form-urlencoded 型のデータ) を解析します。解析されたデータを辞書として返します。辞書のキーは一意なクエリ変数名で、値は各変数名に対する値からなるリストです。

  任意の引数 keep_blank_values は、パーセントエンコードされたクエリの中の値が入っていないクエリの値を空白文字列と見なすかどうかを示すフラグです。値が真であれば、値の入っていないフィールドは空文字列のままになります。標準では偽で、値の入っていないフィールドを無視し、そのフィールドはクエリに含まれていないものとして扱います。

  任意の引数 strict_parsing はパース時のエラーをどう扱うかを決めるフラグです。値が偽なら (デフォルトの設定です)、エラーは暗黙のうちに無視します。値が真なら `ValueError` 例外を送出します。

  The optional argument max_num_fields is the maximum number of fields to read. If set, then throws a `ValueError` if there are more than max_num_fields fields read.

  辞書等をクエリ文字列に変換する場合は `urllib.urlencode()` 関数を使用してください。

  バージョン 2.6 で追加: `cgi` モジュールからコピーされてきました。

  バージョン 2.7.16 で変更: Added max_num_fields parameter.

`urlparse.``parse_qsl`(qs[, keep_blank_values[, strict_parsing[, max_num_fields]]])

  文字列引数として渡されたクエリ文字列 (application/x-www-form-urlencoded 型のデータ) を解析します。解析されたデータは名前と値のペアからなるリストです。

  任意の引数 keep_blank_values は、パーセントエンコードされたクエリの中の値が入っていないクエリの値を空白文字列と見なすかどうかを示すフラグです。値が真であれば、値の入っていないフィールドは空文字列のままになります。標準では偽で、値の入っていないフィールドを無視し、そのフィールドはクエリに含まれていないものとして扱います。

  任意の引数 strict_parsing はパース時のエラーをどう扱うかを決めるフラグです。値が偽なら (デフォルトの設定です)、エラーは暗黙のうちに無視します。値が真なら `ValueError` 例外を送出します。

  The optional argument max_num_fields is the maximum number of fields to read. If set, then throws a `ValueError` if there are more than max_num_fields fields read.

  ペアのリストからクエリ文字列を生成する場合には `urllib.urlencode()` 関数を使用します。

  バージョン 2.6 で追加: `cgi` モジュールからコピーされてきました。

  バージョン 2.7.16 で変更: Added max_num_fields parameter.

`urlparse.``urlunparse`(parts)

  `urlparse()` が返すような形式のタプルから URL を構築します。 parts 引数は任意の 6 要素イテラブルです。解析された元の URL が、不要な区切り文字を持っていた場合には、多少違いはあるが等価な URL になるかもしれません (例えばクエリ内容が空の `?` のようなもので、RFC はこれらを等価だと述べています)。

`urlparse.``urlsplit`(urlstring[, scheme[, allow_fragments]])

  `urlparse()` に似ていますが、URL から params を切り離しません。このメソッドは通常、URL の path 部分において、各セグメントにパラメーター指定をできるようにした最近の URL 構文 (RFC 2396 参照) が必要な場合に、 `urlparse()` の代わりに使われます。パスセグメントとパラメーターを分割するためには分割用の関数が必要です。この関数は 5 要素のタプル: (アドレススキーム、ネットワーク上の位置、パス、クエリ、フラグメント識別子) を返します。

  戻り値は実際には `tuple` のサブクラスのインスタンスです。このクラスには以下の読み出し専用の便利な属性が追加されています:

  属性 | インデックス | `値` | 指定されなかった場合の値
  --- | --- | --- | ---
  `scheme` | 0 | URL スキーム | scheme パラメータ
  `netloc` | 1 | ネットワーク上の位置 | 空文字列
  `path` | 2 | 階層的パス | 空文字列
  `query` | 3 | クエリ要素 | 空文字列
  `fragment` | 4 | フラグメント識別子 | 空文字列
  `username` |  | ユーザ名 | `None`
  `password` |  | パスワード | `None`
  `hostname` |  | ホスト名 (小文字) | `None`
  `port` |  | ポート番号を表わす整数 (もしあれば) | `None`

  結果オブジェクトのより詳しい情報は urlparse() および urlsplit() の結果 節を参照してください。

  バージョン 2.2 で追加.

  バージョン 2.5 で変更: 戻り値に属性が追加されました。

`urlparse.``urlunsplit`(parts)

  `urlsplit()` が返すような形式のタプル中のエレメントを組み合わせて、文字列の完全な URL にします。 parts 引数は任意の 5 要素イテラブルです。解析された元の URL が、不要な区切り文字を持っていた場合には、多少違いはあるが等価な URL になるかもしれません (例えばクエリ内容が空の ? のようなもので、RFC はこれらを等価だと述べています)。

  バージョン 2.2 で追加.

`urlparse.``urljoin`(base, url[, allow_fragments])

  "基底 URL"(base)と別のURL(url)を組み合わせて、完全な URL ("絶対 URL") を構成します。ぶっちゃけ、この関数は基底 URL の要素、特にアドレススキーム、ネットワーク上の位置、およびパス (の一部) を使って、相対 URL にない要素を提供します。以下の例のようになります:

      >>> from urlparse import urljoin
      >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
      'http://www.cwi.nl/%7Eguido/FAQ.html'

  allow_fragments 引数は `urlparse()` における引数と同じ意味とデフォルトを持ちます。

  注釈

  url が (`//` か `scheme://` で始まっている) 絶対URLであれば、その url のホスト名と / もしくは scheme は結果に反映されます。例えば:

      >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html',
      ...         '//www.python.org/%7Eguido')
      'http://www.python.org/%7Eguido'

  もしこの動作が望みのものでない場合は、 url を `urlsplit()` と `urlunsplit()` で先に処理して、 scheme と netloc を削除してください。

`urlparse.``urldefrag`(url)

  url がフラグメント識別子を含む場合、フラグメント識別子を持たないバージョンに修正された url と、別の文字列に分割されたフラグメント識別子を返します。 url 中にフラグメント識別子がない場合、そのままの url と空文字列を返します。

参考

RFC 3986 - Uniform Resource Identifiers
  これが現在の標準規格 (STD66) です。urlparse モジュールに対するすべての変更はこの規格に準拠していなければなりませんが、若干の逸脱はありえます。これは主には後方互換性のため、また主要なブラウザで一般的に見られる、URL を解析する上でのいくつかの事実上の要件を満たすためです。
RFC 2732 - Format for Literal IPv6 Addresses in URL's.
  この規格は IPv6 の URL を解析するときの要求事項を記述しています。
RFC 2396 - Uniform Resource Identifiers (URI): Generic Syntax
  この RFC では Uniform Resource Name (URN) と Uniform Resource Locator (URL) の両方に対する一般的な文法的要求事項を記述しています。
RFC 2368 - The mailto URL scheme.
  mailto URL スキームに対する文法的要求事項です。
RFC 1808 - Relative Uniform Resource Locators
  この RFC には絶対 URL と相対 URL を結合するための規則がボーダケースの取扱い方を決定する "異常な例" つきで収められています。
RFC 1738 - Uniform Resource Locators (URL)
  この RFC では絶対 URL の形式的な文法と意味付けを仕様化しています。

## 20.16.1. `urlparse()` および `urlsplit()` の結果

`urlparse()` および `urlsplit()` から得られる結果オブジェクトはそれぞれ `tuple` 型のサブクラスです。これらのクラスはそれぞれの関数の説明の中で述べたような属性とともに、追加のメソッドを一つ提供しています。

`ParseResult.``geturl`()

  再結合された形で元の URL の文字列を返します。この文字列は元の URL とは次のような点で異なるかもしれません。スキームは常に小文字に正規化されます。また空の要素は省略されます。特に、空のパラメータ、クエリ、フラグメント識別子は取り除かれます。

  加えた解析関数を逆に行えばこのメソッドの戻り値は元の URL になります:

      >>> import urlparse
      >>> url = 'HTTP://www.Python.org/doc/#'

      >>> r1 = urlparse.urlsplit(url)
      >>> r1.geturl()
      'http://www.Python.org/doc/'

      >>> r2 = urlparse.urlsplit(r1.geturl())
      >>> r2.geturl()
      'http://www.Python.org/doc/'

  バージョン 2.5 で追加.

以下のクラスが解析結果の実装を提供します:

class `urlparse.``ParseResult`(scheme, netloc, path, params, query, fragment)

  `urlparse()` の返り値の具象クラス。

class `urlparse.``SplitResult`(scheme, netloc, path, query, fragment)

  `urlsplit()` の返り値の具象クラス。