"urllib.parse" --- URL を構成要素に解析する
*******************************************

**ソースコード:** Lib/urllib/parse.py

======================================================================

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

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

"itms-services" URL スキームが含まれていると、macOS や iOS 向け App
Store の審査にアプリが通らなくなる場合があります。 iOS では "itms-
services" スキームの処理が常に除去されます。 macOS では、CPython を "
--with-app-store-compliance" オプション付きでビルドした場合に除去され
る *ことがあります*。

"urllib.parse" モジュールが定義する関数は、URL の解析と URL のクオート
の大きく二つに分類されます。 以下の節で詳しく説明します。

このモジュールの関数では、**RFC 1808** で導入された非推奨の用語
"netloc" (または "net_loc") を使っています。 ただし、この用語は **RFC
3986** で廃止され、代わりに "authority" が導入されています。 後方互換
性のため、"netloc" を引き続き使っています。


URL の解析
==========

URL 解析関数は、URL 文字列を各構成要素に分割するか、あるいは URL の構
成要素を組み合わせて URL 文字列を生成します。

urllib.parse.urlsplit(urlstring, scheme=None, allow_fragments=True, *, missing_as_none=False)

   URL を五つの構成要素に解析し、5 要素の *名前付きタプル* である
   "SplitResult" または "SplitResultBytes" を返します。 これは URL の
   一般的な構造 "scheme://netloc/path?query#fragment" に対応します。
   各要素は文字列 (空文字列の場合もあります)、または *missing_as_none*
   が真の場合は "None" です。 定義されていない構成要素は、デフォルトで
   は空文字列で、*missing_as_none* が真の場合は "None" で表されます。
   上記の区切り文字は結果に含まれませんが、*path* 要素の先頭のスラッシ
   ュは存在すれば保持されます。

   さらに、"netloc" プロパティを分解した "username"、"password"、
   "hostname"、"port" という属性が、返されるオブジェクトに追加されます
   。

   パーセントエンコードされたシーケンスはデコードされません。

   例えば:

      >>> from urllib.parse import urlsplit
      >>> urlsplit("scheme://netloc/path?query#fragment")
      SplitResult(scheme='scheme', netloc='netloc', path='/path',
                  query='query', fragment='fragment')
      >>> o = urlsplit("http://docs.python.org:80/3/library/urllib.parse.html?"
      ...              "highlight=params#url-parsing")
      >>> o
      SplitResult(scheme='http', netloc='docs.python.org:80',
                  path='/3/library/urllib.parse.html',
                  query='highlight=params', fragment='url-parsing')
      >>> o.scheme
      'http'
      >>> o.netloc
      'docs.python.org:80'
      >>> o.hostname
      'docs.python.org'
      >>> o.port
      80
      >>> o._replace(fragment="").geturl()
      'http://docs.python.org:80/3/library/urllib.parse.html?highlight=params'
      >>> urlsplit("http://docs.python.org?")
      SplitResult(scheme='http', netloc='docs.python.org', path='',
                  query='', fragment='')
      >>> urlsplit("http://docs.python.org?", missing_as_none=True)
      SplitResult(scheme='http', netloc='docs.python.org', path='',
                  query='', fragment=None)

   **RFC 1808** の構文仕様に従い、"urlsplit()" は netloc の前に適切に
   '//' が付いている場合にのみ netloc を認識します。 それ以外の入力は
   相対 URL と見なされ、パス要素で始まるものとして扱われます。

      >>> from urllib.parse import urlsplit
      >>> urlsplit('//www.cwi.nl:80/%7Eguido/Python.html')
      SplitResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
                  query='', fragment='')
      >>> urlsplit('www.cwi.nl/%7Eguido/Python.html')
      SplitResult(scheme='', netloc='', path='www.cwi.nl/%7Eguido/Python.html',
                  query='', fragment='')
      >>> urlsplit('help/Python.html')
      SplitResult(scheme='', netloc='', path='help/Python.html',
                  query='', fragment='')
      >>> urlsplit('help/Python.html', missing_as_none=True)
      SplitResult(scheme=None, netloc=None, path='help/Python.html',
                  query=None, fragment=None)

   *scheme* 引数は、URL にスキームが指定されていない場合にだけ使うデフ
   ォルトのアドレススキームを指定します。 *urlstring* と同じ型 (テキス
   トまたはバイト列) か "None" でなければなりません。 ただし "''" は常
   に使うことができ、必要に応じて自動的に "b''" に変換されます。

   *allow_fragments* 引数が偽の場合、フラグメント識別子は認識されませ
   ん。 代わりにパスまたはクエリ要素の一部として解析され、戻り値の
   "fragment" は *missing_as_none* の値に応じて "None" または空文字列
   になります。

   戻り値は *名前付きタプル* です。これは、インデックス指定もしくは以
   下のような名前属性で要素にアクセスできることを意味します:

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

   [1] *missing_as_none* 引数の値によります。

   URL中で不正なポートが指定されている場合、 "port" 属性を読みだすと、
   "ValueError" を送出します。結果オブジェクトのより詳しい情報は 構造
   化された解析結果 節を参照してください。

   "netloc" 属性にマッチしなかった角括弧があると "ValueError" を送出し
   ます。

   IDNA エンコーディングで使われる NFKC 正規化により "/"、"?"、"#"、
   "@"、":" のいずれかに分解される文字が "netloc" 属性に含まれていると
   、"ValueError" を送出します。 解析前に URL を分解した場合、エラーは
   送出されません。

   **RFC 3986** を更新する WHATWG spec の一部に従い、URL の先頭にある
   C0 制御文字と空白文字は取り除かれます。 "\n"、"\r"、タブ "\t" は
   URL のどの位置にあっても取り除かれます。

   他の名前付きタプルと同様に、このサブクラスには特に便利なメソッドや
   属性がいくつか追加されています。 その一つが "_replace()" メソッドで
   す。 "_replace()" は指定したフィールドを新しい値に置き換えた、新し
   い "SplitResult" オブジェクトを返します。

      >>> from urllib.parse import urlsplit
      >>> u = urlsplit('//www.cwi.nl:80/%7Eguido/Python.html')
      >>> u
      SplitResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
                  query='', fragment='')
      >>> u._replace(scheme='http')
      SplitResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
                  query='', fragment='')

   警告:

     "urlsplit()" は妥当性を検証しません。 詳しくは URL 解析のセキュリ
     ティ を参照してください。

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

   バージョン 3.3 で変更: **RFC 3986** に従い、*allow_fragments* が偽
   でない限り、すべての URL スキームでフラグメントを解析するようになり
   ました。 以前は、フラグメントをサポートするスキームの許可リストがあ
   りました。

   バージョン 3.6 で変更: 範囲外のポート番号に対して、"None" を返す代
   わりに "ValueError" を送出するようになりました。

   バージョン 3.8 で変更: NFKC 正規化により netloc の解析に影響する文
   字があると、"ValueError" を送出するようになりました。

   バージョン 3.10 で変更: URL から ASCII の改行文字とタブ文字を取り除
   くようになりました。

   バージョン 3.12 で変更: 先頭にある WHATWG の C0 制御文字と空白文字
   を取り除くようになりました。

   バージョン 3.15 で変更: *missing_as_none* パラメータが追加されまし
   た。

urllib.parse.parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')

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

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

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

   任意のパラメータ *encoding* および *errors* はパーセントエンコード
   されたシーケンスを Unicode 文字にデコードする方法を指定します。これ
   は "bytes.decode()" メソッドに渡されます。

   任意の引数 *max_num_fields* は読み込むフィールド数の上限です。 指定
   した場合、読み込むフィールド数が *max_num_fields* を超えると
   "ValueError" を送出します。

   任意の引数 *separator* はクエリ引数を区切るための記号です。 デフォ
   ルトは "&" です。

   このような辞書をクエリ文字列に変換するには
   "urllib.parse.urlencode()" 関数を ("doseq" パラメータに "True" を指
   定して) 使用します。

   バージョン 3.2 で変更: *encoding* および *errors* パラメータが追加
   されました。

   バージョン 3.8 で変更: *max_num_fields* パラメータが追加されました
   。

   バージョン 3.10 で変更: *separator* パラメータが追加されました。 デ
   フォルト値は "&" です。 Python 3.10 より前のバージョンでは、クエリ
   パラメータの区切り文字として ";" と "&" の両方を使えました。 この仕
   様を変更し、区切り文字として使えるのは一種類だけになりました。 デフ
   ォルトの区切り文字は "&" です。

   バージョン 3.14 で非推奨: 空の文字列やバイト列類似オブジェクト、お
   よび "None" を除き、偽となる値を持つオブジェクト ("0" や "[]" など)
   を受け付けることは非推奨になりました。

urllib.parse.parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')

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

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

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

   任意のパラメータ *encoding* および *errors* はパーセントエンコード
   されたシーケンスを Unicode 文字にデコードする方法を指定します。これ
   は "bytes.decode()" メソッドに渡されます。

   任意の引数 *max_num_fields* は読み込むフィールド数の上限です。 指定
   した場合、読み込むフィールド数が *max_num_fields* を超えると
   "ValueError" を送出します。

   任意の引数 *separator* はクエリ引数を区切るための記号です。 デフォ
   ルトは "&" です。

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

   バージョン 3.2 で変更: *encoding* および *errors* パラメータが追加
   されました。

   バージョン 3.8 で変更: *max_num_fields* パラメータが追加されました
   。

   バージョン 3.10 で変更: *separator* パラメータが追加されました。 デ
   フォルト値は "&" です。 Python 3.10 より前のバージョンでは、クエリ
   パラメータの区切り文字として ";" と "&" の両方を使えました。 この仕
   様を変更し、区切り文字として使えるのは一種類だけになりました。 デフ
   ォルトの区切り文字は "&" です。

urllib.parse.urlunsplit(parts)
urllib.parse.urlunsplit(parts, *, keep_empty)

   "urlsplit()" が返すようなタプルから URL を構築します。 *parts* 引数
   には、5 要素の任意のイテラブルを指定できます。

   元の URL に不要な区切り文字 (空のクエリに付く "?" など) が含まれて
   いた場合、結果は元の URL と少し異なるものの等価な URL になることが
   あります (RFC では両者を等価としています)。

   *keep_empty* が真の場合、空文字列を結果に保持し (空のクエリを表す
   "?" など)、"None" の要素だけを省きます。 これにより、
   "missing_as_none=True" オプションで解析した URL を復元できます。 デ
   フォルトでは、*parts* が "missing_as_none=True" を指定した
   "urlsplit()" の呼び出し結果であれば、*keep_empty* は真になります。

   バージョン 3.15 で変更: *keep_empty* パラメータが追加されました。

urllib.parse.urlparse(urlstring, scheme=None, allow_fragments=True, *, missing_as_none=False)

   "urlsplit()" と似ていますが、さらに *path* 要素を *path* と
   *params* に分割します。 6 要素の *名前付きタプル* である
   "ParseResult" または "ParseResultBytes" を返します。 要素は
   "urlsplit()" の結果と同じですが、*path* と *query* の間のインデック
   ス 3 に *params* が挿入されます。

   この関数は廃止された **RFC 1738** と **RFC 1808** に基づいており、
   これらの RFC は *params* を URL の主要な構成要素としていました。 よ
   り新しい URL 構文では、URL の *path* 部分の各セグメントにパラメータ
   を付けることができます (**RFC 3986** を参照)。 通常は "urlparse()"
   の代わりに "urlsplit()" を使うべきです。 パスのセグメントとパラメー
   タを分離するには別の関数が必要です。

urllib.parse.urlunparse(parts)
urllib.parse.urlunparse(parts, *, keep_empty)

   "urlparse()" が返すようなタプルの要素を結合し、完全な URL を文字列
   として生成します。 *parts* 引数には、6 要素の任意のイテラブルを指定
   できます。

   元の URL に不要な区切り文字 (空のクエリに付く "?" など) が含まれて
   いた場合、結果は元の URL と少し異なるものの等価な URL になることが
   あります (RFC では両者を等価としています)。

   *keep_empty* が真の場合、空文字列を結果に保持し (空のクエリを表す
   "?" など)、"None" の要素だけを省きます。 これにより、
   "missing_as_none=True" オプションで解析した URL を復元できます。 デ
   フォルトでは、*parts* が "missing_as_none=True" を指定した
   "urlparse()" の呼び出し結果であれば、*keep_empty* は真になります。

   バージョン 3.15 で変更: *keep_empty* パラメータが追加されました。

urllib.parse.urljoin(base, url, allow_fragments=True)

   "基底 URL"(*base*)と別のURL(*url*)を組み合わせて、完全な URL ("絶対
   URL") を構成します。くだけて言えば、この関数は相対 URL にない要素を
   提供するために基底 URL の要素、特にアドレススキーム、ネットワーク上
   の位置、およびパス (の一部) を使います。例えば:

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

   *allow_fragments* 引数の意味とデフォルト値は "urlsplit()" と同じで
   す。

   注釈:

     *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* を削除してく
     ださい。

   警告:

     "url" パラメータには絶対 URL も渡せるため、攻撃者が制御できる
     "url" を "urljoin" に渡すことは一般に **安全ではありません**。 例
     えば "urljoin("https://website.com/users/", username)" で
     "username" に絶対 URL が含まれ得る場合、"urljoin" の結果はその絶
     対 URL になります。

   バージョン 3.5 で変更: **RFC 3986** で定義された意味論とマッチする
   ように挙動がアップデートされました。

urllib.parse.urldefrag(url, *, missing_as_none=False)

   *url* にフラグメント識別子が含まれている場合、フラグメント識別子を
   取り除いた *url* と、フラグメント識別子を別の文字列として返します。
   *url* にフラグメント識別子が含まれていない場合は、変更していない
   *url* と、デフォルトでは空文字列、*missing_as_none* が真の場合は
   "None" を返します。

   戻り値は *名前付きタプル* で、インデックスによってもしくは名前属性
   として要素にアクセスできます:

   +--------------------+---------+---------------------------+---------------------------------+
   | 属性               | インデ  | 値                        | 指定されなかった場合の値        |
   |                    | ックス  |                           |                                 |
   |====================|=========|===========================|=================================|
   | "url"              | 0       | フラグメントのない URL    | 空文字列                        |
   +--------------------+---------+---------------------------+---------------------------------+
   | "fragment"         | 1       | フラグメント識別子        | "None" または空文字列 [3]       |
   +--------------------+---------+---------------------------+---------------------------------+

   [3] *missing_as_none* 引数の値によります。

   結果オブジェクトのより詳しい情報は 構造化された解析結果 節を参照し
   てください。

   バージョン 3.2 で変更: 結果はシンプルな 2 要素のタプルから構造化オ
   ブジェクトに変更されました。

   バージョン 3.15 で変更: *missing_as_none* パラメータが追加されまし
   た。

urllib.parse.unwrap(url)

   ラップされた URL ("<URL:scheme://host/path>"、
   "<scheme://host/path>"、"URL:scheme://host/path"、
   "scheme://host/path" のいずれかの形式の文字列) から URL を取り出し
   ます。 *url* がラップされた URL でなければ、そのまま返します。


URL 解析のセキュリティ
======================

"urlsplit()" と "urlparse()" の API は入力の **妥当性を検証しません**
。 他のアプリケーションが無効と見なす入力に対して、エラーを送出しない
ことがあります。 他では URL と見なされない入力でも、解析が成功する場合
があります。 これらの API は厳密さよりも実用的な機能を目的としています
。

通常とは異なる入力に対して例外を送出する代わりに、一部の構成要素を空文
字列や "None" として返すことがあります (*missing_as_none* 引数の値によ
ります)。 また、構成要素に本来含めるべきでない部分まで含まれることもあ
ります。

これらの API の返す値をセキュリティに影響する場面で使う可能性がある場
合は、防御的なコードを書くことを推奨します。 返された構成要素を信用す
る前に、自分のコードで検証してください。 例えば、"scheme" は適切か、
"path" は妥当か、"hostname" に不審な点はないか、といったことを確認して
ください。

何を URL とするかについて、普遍的で明確な定義はありません。 アプリケー
ションごとに要件や求める制約は異なります。 例えば、随時更新される
WHATWG spec は Web ブラウザなどの利用者向け Web クライアントに必要な仕
様を記述していますが、**RFC 3986** はより一般的な仕様です。 これらの関
数は両方の仕様の一部を取り入れていますが、どちらにも準拠しているとは言
えません。 API や、特定の動作を期待する既存の利用者コードは、どちらの
標準よりも前から存在しています。 そのため、API の動作の変更には非常に
慎重になっています。


ASCII エンコードバイト列の解析
==============================

URL を解析する関数は元々文字列のみ操作するよう設計されていました。実際
のところ、それは URL が正しくクオートされエンコードされた ASCII バイト
列を操作できた方が有用でした。結果的にこのモジュールの URL 解析関数は
すべて "bytes" および "bytearray" オブジェクトに加えて "str" オブジェ
クトでも処理するようになりました。

"str" データが渡された場合、戻り値は "str" データのみを含んだものにな
ります。"bytes" あるいは "bytearray" が渡された場合、戻り値は "bytes"
データのみを含んだものになります。

単一の関数を呼び出す時に "bytes" または "bytearray" が混在した "str"
を渡した場合、"TypeError" が、非 ASCII バイト値が渡された場合
"UnicodeDecodeError" が送出されます。

結果オブジェクトを "str" と "bytes" の間で変換しやすくするため、URL 解
析関数のすべての戻り値には、"str" データを含む場合は "encode()" メソッ
ド、"bytes" データを含む場合は "decode()" メソッドがあります。 これら
のメソッドのシグネチャは、対応する "str" および "bytes" のメソッドと同
じです (ただし、デフォルトのエンコーディングは "'utf-8'" ではなく
"'ascii'" です)。 "encode()" は "bytes" データを含む対応する型の値を生
成し、"decode()" は "str" データを含む対応する型の値を生成します。

非 ASCII データを含むなど、不適切にクオートされた URL を操作する可能性
のあるアプリケーションでは、URL 解析メソッドを呼び出す前に独自にバイト
列から文字列にデコードする必要があります。

この項で説明された挙動は URL 解析関数にのみ該当します。URL クオート関
数でバイトシーケンスを生成もしくは消化する際には、別にURL クオート関数
の項で詳説されている通りのルールに従います。

バージョン 3.2 で変更: URL 解析関数は ASCII エンコードバイトシーケンス
も受け付けるようになりました


構造化された解析結果
====================

"urlsplit()"、"urlparse()"、"urldefrag()" が返す結果オブジェクトは
"tuple" 型のサブクラスです。 これらのサブクラスには、各関数のドキュメ
ントに記載した属性、前節で説明したエンコードとデコードの機能に加え、次
のメソッドがあります:

urllib.parse.SplitResult.geturl()

   元の URL を再結合した文字列を返します。 スキームが小文字に正規化さ
   れたり、空の構成要素が取り除かれたりするため、元の URL と異なる場合
   があります。 具体的には、"missing_as_none=True" を指定して URL を解
   析した場合を除き、空のパラメータ、クエリ、フラグメント識別子が取り
   除かれます。

   "urldefrag()" の戻り値では、空のフラグメント識別子のみ削除されます
   。"urlsplit()" および "urlparse()" の戻り値では、このメソッドが返す
   URL には説明されているすべての変更が加えられます。

   このメソッドの結果を元の解析関数で再び解析しても、このメソッドの結
   果は変わりません。

   >>> from urllib.parse import urlsplit
   >>> url = 'HTTP://www.Python.org/doc/#'
   >>> r1 = urlsplit(url)
   >>> r1.geturl()
   'http://www.Python.org/doc/'
   >>> r2 = urlsplit(r1.geturl())
   >>> r2.geturl()
   'http://www.Python.org/doc/'
   >>> r3 = urlsplit(url, missing_as_none=True)
   >>> r3.geturl()
   'http://www.Python.org/doc/#'

以下のクラスは "str" オブジェクトを操作した場合、構造化された解析結果
の実装を提供します:

class urllib.parse.DefragResult(url, fragment)

   "str" データを含む "urldefrag()" の戻り値を表す具象クラスです。
   "encode()" メソッドは "DefragResultBytes" インスタンスを返します。

   Added in version 3.2.

class urllib.parse.ParseResult(scheme, netloc, path, params, query, fragment)

   "str" データを含む "urlparse()" の戻り値を表す具象クラスです。
   "encode()" メソッドは "ParseResultBytes" インスタンスを返します。

class urllib.parse.SplitResult(scheme, netloc, path, query, fragment)

   "str" データを含む "urlsplit()" の戻り値を表す具象クラスです。
   "encode()" メソッドは "SplitResultBytes" インスタンスを返します。

以下のクラスは "bytes" または "bytearray" オブジェクトを操作した時に解
析結果の実装を提供します:

class urllib.parse.DefragResultBytes(url, fragment)

   "bytes" データを含む "urldefrag()" の戻り値を表す具象クラスです。
   "decode()" メソッドは "DefragResult" インスタンスを返します。

   Added in version 3.2.

class urllib.parse.ParseResultBytes(scheme, netloc, path, params, query, fragment)

   "bytes" データを含む "urlparse()" の戻り値を表す具象クラスです。
   "decode()" メソッドは "ParseResult" インスタンスを返します。

   Added in version 3.2.

class urllib.parse.SplitResultBytes(scheme, netloc, path, query, fragment)

   "bytes" データを含む "urlsplit()" の戻り値を表す具象クラスです。
   "decode()" メソッドは "SplitResult" インスタンスを返します。

   Added in version 3.2.


URL のクオート
==============

URL クオート関数は、プログラムデータを取り URL 構成要素として使用でき
るよう特殊文字をクオートしたり非 ASCII 文字を適切にエンコードすること
に焦点を当てています。これらは上述の URL 解析関数でカバーされていない
URL 構成要素からオリジナルデータの再作成もサポートしています。

urllib.parse.quote(string, safe='/', encoding=None, errors=None)

   *string* 内の特殊文字を "%*xx*" を使用してエスケープします。 英字、
   数字、および "'_.-~'" はクオートされません。 デフォルトでは、この関
   数は URL のパス部分のクオートのために用意されています。 任意のパラ
   メータ *safe* を指定すると、指定した ASCII 文字もクオートされません
   。 デフォルトは "'/'" です。

   *string* に使用できるのは "str" か "bytes" オブジェクトです。

   バージョン 3.7 で変更: URL 文字列のクオートの規則を **RFC 2396** か
   ら **RFC 3986** に変更しました。 "~" が非予約文字に含まれるようにな
   りました。

   任意のパラメータ *encoding* と *errors* は、"str.encode()" メソッド
   が受け付ける値を使い、非 ASCII 文字の扱い方を指定します。 関数シグ
   ネチャではどちらもデフォルト値が "None" ですが、"str" の入力を処理
   するときの実質的なデフォルト値は、*encoding* が "'utf-8'"、*errors*
   が "'strict'" です。 これは、サポートされない文字に対して
   "UnicodeEncodeError" を送出することを意味します。 *string* が
   "bytes" の場合、*encoding* と *errors* を指定してはなりません。 指
   定すると "TypeError" を送出します。

   "quote(string, safe, encoding, errors)" は
   "quote_from_bytes(string.encode(encoding, errors), safe)" と等価で
   あることに留意してください。

   例: "quote('/El Niño/')" は "'/El%20Ni%C3%B1o/'" を返します。

urllib.parse.quote_plus(string, safe='', encoding=None, errors=None)

   "quote()" と似ていますが、URL に含めるクエリ文字列を作る際に HTML
   フォームの値をクオートするために必要な処理として、空白をプラス記号
   にも置き換えます。 元の文字列のプラス記号は、*safe* に含まれていな
   ければエスケープされます。 また、*safe* のデフォルト値は "'/'" では
   ありません。

   例: "quote_plus('/El Niño/')" は "'%2FEl+Ni%C3%B1o%2F'" を返します
   。

urllib.parse.quote_from_bytes(bytes, safe='/')

   "quote()" と似ていますが、"str" ではなく "bytes" オブジェクトを取り
   、文字列からバイト列へのエンコードを行いません。

   例: "quote_from_bytes(b'a&\xef')" は "'a%26%EF'" を返します。

urllib.parse.unquote(string, encoding='utf-8', errors='replace')

   エスケープされた "%*xx*" をそれに対応した単一文字に置き換えます。オ
   プション引数の *encoding* と *errors* は "bytes.decode()" メソッド
   で受け付けられるパーセントエンコードされたシーケンスから Unicode 文
   字へのデコード法を指定します。

   *string* に使用できるのは "str" か "bytes" オブジェクトです。

   *encoding* のデフォルトは "'utf-8'"、*errors* のデフォルトは
   "'replace'" で、不正なシーケンスはプレースホルダー文字に置き換えら
   れます。

   例: "unquote('/El%20Ni%C3%B1o/')" は "'/El Niño/'" を返します。

   バージョン 3.9 で変更: *string* パラメータが bytes と str の両方の
   オブジェクトをサポートするようになりました (以前は str だけでした)
   。

urllib.parse.unquote_plus(string, encoding='utf-8', errors='replace')

   "unquote()" と似ていますが、HTML フォームの値のアンクオートのために
   「+」を空白に置き換えます。

   *string* は "str" でなければなりません。

   例: "unquote_plus('/El+Ni%C3%B1o/')" は "'/El Niño/'" を返します。

urllib.parse.unquote_to_bytes(string)

   エスケープ表記 "%*xx*" を対応する 1 オクテットの値に置き換え、
   "bytes" オブジェクトを返します。

   *string* に使用できるのは "str" か "bytes" オブジェクトです。

   "str" だった場合、*string* 内のエスケープされていない非 ASCII 文字
   は UTF-8 バイト列にエンコードされます。

   例: "unquote_to_bytes('a%26%EF')" は "b'a&\xef'" を返します。

urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus)

   マッピング型オブジェクトまたは 2 個の要素からなるタプルのシーケンス
   ("str" か "bytes" オブジェクトが含まれているかもしれません) を、パ
   ーセントエンコードされた ASCII 文字列に変換します。戻り値の文字列が
   "urlopen()" 関数での POST 操作の *data* で使用される場合はバイト列
   にエンコードしなければなりません。そうでない場合は "TypeError" が送
   出されます。

   戻り値は "'&'" 文字で区切られた "key=value" のペアからなる一組の文
   字列になります。 *key* と *value* は *quote_via* を使用してクオート
   されます。デフォルトで、値をクォートするために "quote_plus()" が使
   用されます。つまり、スペースは "'+'" 文字に、 '/' 文字は "%2F" にク
   ォートされます。これは GET リクエストの標準に準拠します
   ("application/x-www-form-urlencoded")。 *quote_via* として渡すこと
   ができる別の関数は "quote()" です。それはスペースを "%20" にエンコ
   ードし、 '/' をエンコードしません。何がクォートされるかを最大限コン
   トロールしたければ、 "quote" を使って *safe* に値を指定してください
   。

   引数 *query* が 2 要素のタプルのシーケンスの場合、各タプルの第一要
   素はキーに、第二要素は値になります。 値となる要素はシーケンスを取る
   こともでき、この場合、オプションのパラメーター *doseq* が "True" と
   評価されるのであれば、キーに対し値シーケンスの各要素を個別に結び付
   けた "key=value" のペアを、 "'&'" 文字でつないだものを生成します。
   エンコードされた文字列内のパラメーターの順序はシーケンス内のパラメ
   ータータプルの順序と一致します。

   *safe*、*encoding*、*errors* パラメータは *quote_via* に渡されます
   。 ただし、*encoding* と *errors* が渡されるのはクエリの要素が
   "str" の場合だけです。

   このエンコード処理の逆を行うには、このモジュールで提供されている
   "parse_qs()" と "parse_qsl()" を使用して、クエリ文字列を Python デ
   ータ構造に変換できます。

   POST リクエストのデータ、あるいは URL クエリ文字列を生成するために
   、 "urllib.parse.urlencode()" メソッドをどのように使えばよいかを見
   るには、urllib の使用例 を参照してください。

   バージョン 3.2 で変更: *query* はバイト列と文字列オブジェクトをサポ
   ートします。

   バージョン 3.5 で変更: *quote_via* パラメータが追加されました。

   バージョン 3.14 で非推奨: 空の文字列やバイト列類似オブジェクト、お
   よび "None" を除き、偽となる値を持つオブジェクト ("0" や "[]" など)
   を受け付けることは非推奨になりました。

参考:

  WHATWG - 随時更新される URL 標準
     URL、ドメイン、IP アドレス、application/x-www-form-urlencoded 形
     式、およびそれらの API を定義する URL 標準の作業部会。

  **RFC 3986** - Uniform Resource Identifiers
     これが現在の標準規格 (STD66) です。urllib.parse モジュールに対す
     るすべての変更はこの規格に準拠していなければなりませんが、若干の
     逸脱はありえます。これは主には後方互換性のため、また主要なブラウ
     ザで一般的に見られる、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 の形式的な文法と意味付けを仕様化しています
     。
