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()" の返り値の具象クラス。
