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, mailto, mms, news, nntp, prospero, rsync, rtsp, rtspu, sftp, shttp, sip, sips, snews, svn, svn+ssh, telnet, wais, ws, wss

urllib.parse モジュールは、大きく分けると URL の解析を行う関数と URL のクオートを行う関数を定義しています。以下にこれらの詳細を説明します。

URL の解析

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

urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)

Parse a URL into six components, returning a 6-item named tuple. This corresponds to the general structure of a URL: scheme://netloc/path;parameters?query#fragment. Each tuple item is a string, possibly empty. The components are not broken up in smaller parts (for example, the network location is a single string), and % escapes are not expanded. The delimiters as shown above are not part of the result, except for a leading slash in the path component, which is retained if present. For example:

>>> from urllib.parse import urlparse
>>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
>>> o   
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 urllib.parse 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 のみに使用されます。常に許されるデフォルトの '' (b'' に自動変換出来る)を除き、 urlstring と同じ型(テキストもしくはバイト列)であるべきです。

引数 allow_fragments が false の場合、フラグメント識別子は認識されません。その代わり、それはパス、パラメータ、またはクエリ要素の一部として解析され、戻り値の fragment は空文字に設定されます。

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

属性

インデックス

指定されなかった場合の値

scheme

0

URL スキーム

scheme パラメータ

netloc

1

ネットワーク上の位置

空文字列

path

2

階層的パス

空文字列

params

3

最後のパス要素に対するパラメータ

空文字列

query

4

クエリ要素

空文字列

fragment

5

フラグメント識別子

空文字列

username

ユーザ名

None

password

パスワード

None

hostname

ホスト名 (小文字)

None

port

ポート番号を表わす整数 (もしあれば)

None

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

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

Characters in the netloc attribute that decompose under NFKC normalization (as used by the IDNA encoding) into any of /, ?, #, @, or : will raise a ValueError. If the URL is decomposed before parsing, no error will be raised.

As is the case with all named tuples, the subclass has a few additional methods and attributes that are particularly useful. One such method is _replace(). The _replace() method will return a new ParseResult object replacing specified fields with new values.

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

警告

urlparse() does not perform validation. See URL parsing security for details.

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

バージョン 3.3 で変更: RFC 3986 に従い、fragment はすべての URL スキームに対して解析されるようになりました (allow_fragment が偽の場合は除く)。

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

バージョン 3.7.3 で変更: Characters that affect netloc parsing under NFKC normalization will now raise ValueError.

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() メソッドに渡されます。

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.

The optional argument separator is the symbol to use for separating the query arguments. It defaults to &.

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

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

バージョン 3.7.2 で変更: max_num_fields 引数が追加されました。

バージョン 3.7.10 で変更: Added separator parameter with the default value of &. Python versions earlier than Python 3.7.10 allowed using both ; and & as query parameter separator. This has been changed to allow only a single separator key, with & as the default separator.

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() メソッドに渡されます。

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.

The optional argument separator is the symbol to use for separating the query arguments. It defaults to &.

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

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

バージョン 3.7.2 で変更: max_num_fields 引数が追加されました。

バージョン 3.7.10 で変更: Added separator parameter with the default value of &. Python versions earlier than Python 3.7.10 allowed using both ; and & as query parameter separator. This has been changed to allow only a single separator key, with & as the default separator.

urllib.parse.urlunparse(parts)

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

urllib.parse.urlsplit(urlstring, scheme='', allow_fragments=True)

urlparse() に似ていますが、URL から params を切り離しません。このメソッドは通常、URL の path 部分において、各セグメントにパラメータ指定をできるようにした最近の URL 構文 (RFC 2396 参照) が必要な場合に、 urlparse() の代わりに使われます。パスセグメントとパラメータを分割するためには分割用の関数が必要です。この関数は 5 要素の term:named tuple を返します:

(addressing scheme, network location, path, query, fragment identifier).

The return value is a named tuple, its items can be accessed by index or as named attributes:

属性

インデックス

指定されなかった場合の値

scheme

0

URL スキーム

scheme パラメータ

netloc

1

ネットワーク上の位置

空文字列

path

2

階層的パス

空文字列

query

3

クエリ要素

空文字列

fragment

4

フラグメント識別子

空文字列

username

ユーザ名

None

password

パスワード

None

hostname

ホスト名 (小文字)

None

port

ポート番号を表わす整数 (もしあれば)

None

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

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

Characters in the netloc attribute that decompose under NFKC normalization (as used by the IDNA encoding) into any of /, ?, #, @, or : will raise a ValueError. If the URL is decomposed before parsing, no error will be raised.

Following some of the WHATWG spec that updates RFC 3986, leading C0 control and space characters are stripped from the URL. \n, \r and tab \t characters are removed from the URL at any position.

警告

urlsplit() does not perform validation. See URL parsing security for details.

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

バージョン 3.7.3 で変更: Characters that affect netloc parsing under NFKC normalization will now raise ValueError.

バージョン 3.7.11 で変更: ASCII newline and tab characters are stripped from the URL.

バージョン 3.7.17 で変更: Leading WHATWG C0 control and space characters are stripped from the URL.

urllib.parse.urlunsplit(parts)

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

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 引数は urlparse() における引数と同じ意味とデフォルトを持ちます。

注釈

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

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

もしこの動作が望みのものでない場合は、 urlurlsplit()urlunsplit() で先に処理して、 schemenetloc を削除してください。

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

urllib.parse.urldefrag(url)

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

The return value is a named tuple, its items can be accessed by index or as named attributes:

属性

インデックス

指定されなかった場合の値

url

0

フラグメントのない URL

空文字列

fragment

1

フラグメント識別子

空文字列

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

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

URL parsing security

The urlsplit() and urlparse() APIs do not perform validation of inputs. They may not raise errors on inputs that other applications consider invalid. They may also succeed on some inputs that might not be considered URLs elsewhere. Their purpose is for practical functionality rather than purity.

Instead of raising an exception on unusual input, they may instead return some component parts as empty strings. Or components may contain more than perhaps they should.

We recommend that users of these APIs where the values may be used anywhere with security implications code defensively. Do some verification within your code before trusting a returned component part. Does that scheme make sense? Is that a sensible path? Is there anything strange about that hostname? etc.

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

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

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

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

strbytes 間で容易に変換を行えるよう、すべての URL 解析関数は encode() メソッド (結果に str データが含まれる時用) か decode() メソッド (結果に bytes データが含まれる時用) のどちらかを提供しています。これらメソッドの動作は対応する strbytes メソッドが持つものと同じです (ただしデフォルトのエンコーディングは 'utf-8' ではなく 'ascii' になります)。それぞれは encode() メソッドを持つ bytes データか decode() メソッドを持つ str データのどちらかに対応した型を生成します。

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

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

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

構造化された解析結果

urlparse()urlsplit()、および urldefrag() 関数が返すオブジェクトは tuple 型のサブクラスになります。これらサブクラスにはそれぞれの関数で説明されている属性が追加されており、前述のとおりエンコーディングとデコーディングをサポートしています:

urllib.parse.SplitResult.geturl()

オリジナルの URL を再結合した場合は文字列で返されます。これはスキームが小文字に正規化されていたり、空の構成要素が除去されるなど、オリジナルの URL とは異なる場合があります。特に、空のパラメータ、クエリ、およびフラグメント識別子は削除されます。

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

加えた解析関数を逆に行えばこのメソッドの戻り値は元の 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/'

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

class urllib.parse.DefragResult(url, fragment)

urldefrag() の具象クラスの結果には str データが含まれます。encode() メソッドは DefragResultBytes インスタンスを返します。

バージョン 3.2 で追加.

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

urlparse() の具象クラスの結果には str データが含まれます。encode() メソッドは ParseResultBytes インスタンスを返します。

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

urlsplit() の具象クラスの結果には str データが含まれます。encode() メソッドは SplitResultBytes インスタンスを返します。

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

class urllib.parse.DefragResultBytes(url, fragment)

urldefrag() の具象クラスの結果には bytes データが含まれます。decode() メソッドは DefragResult インスタンスを返します。

バージョン 3.2 で追加.

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

urlparse() の具象クラスの結果には bytes が含まれます。decode() メソッドは ParseResult インスタンスを返します。

バージョン 3.2 で追加.

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

urlsplit() の具象クラスの結果には bytes データが含まれます。decode() メソッドは SplitResult インスタンスを返します。

バージョン 3.2 で追加.

URL のクオート

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

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

Replace special characters in string using the %xx escape. Letters, digits, and the characters '_.-~' are never quoted. By default, this function is intended for quoting the path section of URL. The optional safe parameter specifies additional ASCII characters that should not be quoted --- its default value is '/'.

string に使用できるのは strbytes です。

バージョン 3.7 で変更: Moved from RFC 2396 to RFC 3986 for quoting URL strings. "~" is now included in the set of unreserved characters.

任意のパラメータ encodingerrorsstr.encode() で受け付けられる非 ASCII 文字への対処法を指定します。encoding のデフォルトは 'utf-8'errors のデフォルトは 'strict' で、非サポート文字があると UnicodeEncodeError を送出します。stringbytes の場合 encodingerrors を指定してはいけません。指定すると 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 をそれに対応した単一文字に置き換えます。オプション引数の encodingerrorsbytes.decode() メソッドで受け付けられるパーセントエンコードされたシーケンスから Unicode 文字へのデコード法を指定します。

stringstr でなければなりません。

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

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

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

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

stringstr でなければなりません。

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

urllib.parse.unquote_to_bytes(string)

スケープされた %xx をそれに対応した 1 オクテットに置き換え、bytes オブジェクトを返します。

string に使用できるのは strbytes です。

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

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

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

safe, encoding, および errors パラメータは quote_via にそのまま渡されます (クエリ要素が str の場合は、 encodingerrors パラメータだけが渡されます)。

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

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

バージョン 3.2 で変更: クエリ文字列にバイト列と文字列オブジェクトをサポートしました。

バージョン 3.5 で追加: quote_via 引数。

参考

WHATWG - URL Living standard

Working Group for the URL Standard that defines URLs, domains, IP addresses, the application/x-www-form-urlencoded format, and their API.

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 の形式的な文法と意味付けを仕様化しています。