urlparse – URL を部分文字列に分割する

目的:URL を部分文字列に分割する
利用できるバージョン:1.4 以上

urlparse モジュールは関連する RFC で定義されているように URL を部分文字列に分解するための機能を提供します。

解析する

urlparse() 関数は6つの要素を持つタプルのように動作するオブジェクトを返します。

from urlparse import urlparse
parsed = urlparse('http://netloc/path;parameters?query=argument#fragment')
print parsed

タプルのインタフェースを通して利用できる URL の部分文字列はスキーマ(scheme), ネットワークロケーション(netloc), パス(path), パラメータ(params), クエリ(query) と フラグメント(fragment) です。

$ python urlparse_urlparse.py
ParseResult(scheme='http', netloc='netloc', path='/path', params='parameters', query='query=argument', fragment='fragment')

返される値はタプルのように動作しますが、実際は namedtuple に基づいています。タプルのサブクラスはインデックスの代わりに属性名を通して URL の部分文字列へアクセスすることをサポートします。プログラマが簡単に使用できるのに加えて、その属性 API はタプル API では利用できない複数の値へのアクセスも提供します。

from urlparse import urlparse
parsed = urlparse('http://user:pass@NetLoc:80/path;parameters?query=argument#fragment')
print 'scheme  :', parsed.scheme
print 'netloc  :', parsed.netloc
print 'path    :', parsed.path
print 'params  :', parsed.params
print 'query   :', parsed.query
print 'fragment:', parsed.fragment
print 'username:', parsed.username
print 'password:', parsed.password
print 'hostname:', parsed.hostname, '(netloc in lower case)'
print 'port    :', parsed.port

usernamepassword は入力 URL に含まれるときに利用できて、含まれないときは None です。 hostnamenetloc と同じ値で全て小文字です。 port は存在するときに整数値へ変換され、存在しないときは None です。

$ python urlparse_urlparseattrs.py
scheme  : http
netloc  : user:pass@NetLoc:80
path    : /path
params  : parameters
query   : query=argument
fragment: fragment
username: user
password: pass
hostname: netloc (netloc in lower case)
port    : 80

urlsplit() 関数は urlparse() に対する代替方法です。その動作は URL からパラメータを分割しないので urlparse() と少し違っています。これは RFC 2396 に従う、そのパスの各セグメントのパラメータをサポートする URL に便利です。

from urlparse import urlsplit
parsed = urlsplit('http://user:pass@NetLoc:80/path;parameters/path2;parameters2?query=argument#fragment')
print parsed
print 'scheme  :', parsed.scheme
print 'netloc  :', parsed.netloc
print 'path    :', parsed.path
print 'query   :', parsed.query
print 'fragment:', parsed.fragment
print 'username:', parsed.username
print 'password:', parsed.password
print 'hostname:', parsed.hostname, '(netloc in lower case)'
print 'port    :', parsed.port

パラメータが分割されないのでタプル API は params 属性のない、6つではなく5つの要素を返します。

$ python urlparse_urlsplit.py
SplitResult(scheme='http', netloc='user:pass@NetLoc:80', path='/path;parameters/path2;parameters2', query='query=argument', fragment='fragment')
scheme  : http
netloc  : user:pass@NetLoc:80
path    : /path;parameters/path2;parameters2
query   : query=argument
fragment: fragment
username: user
password: pass
hostname: netloc (netloc in lower case)
port    : 80

URL からフラグメントの識別子を簡単に取り除くために、また URL からベースページの名前を取得するために urldefrag() を使用する必要があるでしょう。

from urlparse import urldefrag
original = 'http://netloc/path;parameters?query=argument#fragment'
print original
url, fragment = urldefrag(original)
print url
print fragment

ベース URL とそのフラグメントを含むタプルが返されます。

$ python urlparse_urldefrag.py
http://netloc/path;parameters?query=argument#fragment
http://netloc/path;parameters?query=argument
fragment

再構築

分割された URL から1つの文字列へ戻す複数の方法があります。解析された URL オブジェクトは geturl() メソッドを持ちます。

from urlparse import urlparse
original = 'http://netloc/path;parameters?query=argument#fragment'
print 'ORIG  :', original
parsed = urlparse(original)
print 'PARSED:', parsed.geturl()

geturl()urlparse() 又は urlsplit() によって返されるオブジェクトでのみ動作します。

$ python urlparse_geturl.py
ORIG  : http://netloc/path;parameters?query=argument#fragment
PARSED: http://netloc/path;parameters?query=argument#fragment

もし普通のタプルで取得したいなら、URL にそれらを結合するために urlunparse() を使用できます。

from urlparse import urlparse, urlunparse
original = 'http://netloc/path;parameters?query=argument#fragment'
print 'ORIG  :', original
parsed = urlparse(original)
print 'PARSED:', type(parsed), parsed
t = parsed[:]
print 'TUPLE :', type(t), t
print 'NEW   :', urlunparse(t)

urlparse() が返す ParseResult クラスはタプルのようには使用できません。この例では urlunparse() が普通のタプルでも動作することを表すために明示的に新たなタプルを作成します。

$ python urlparse_urlunparse.py
ORIG  : http://netloc/path;parameters?query=argument#fragment
PARSED: <class 'urlparse.ParseResult'> ParseResult(scheme='http', netloc='netloc', path='/path', params='parameters', query='query=argument', fragment='fragment')
TUPLE : <type 'tuple'> ('http', 'netloc', '/path', 'parameters', 'query=argument', 'fragment')
NEW   : http://netloc/path;parameters?query=argument#fragment

入力 URL が余分な文字列を含むなら URL を再構築した文字列からその文字列が欠落します。

from urlparse import urlparse, urlunparse
original = 'http://netloc/path;?#'
print 'ORIG  :', original
parsed = urlparse(original)
print 'PARSED:', type(parsed), parsed
t = parsed[:]
print 'TUPLE :', type(t), t
print 'NEW   :', urlunparse(t)

このケースでは parameters, queryfragment がオリジナルの URL から全て欠落します。新たな URL はオリジナルの URL と同じではありませんが、標準によると等価です。

$ python urlparse_urlunparseextra.py
ORIG  : http://netloc/path;?#
PARSED: <class 'urlparse.ParseResult'> ParseResult(scheme='http', netloc='netloc', path='/path', params='', query='', fragment='')
TUPLE : <type 'tuple'> ('http', 'netloc', '/path', '', '', '')
NEW   : http://netloc/path

結合

URL を解析することに加えて urlparse には関連するフラグメントから相対 URL を構築する urljoin() があります。

from urlparse import urljoin
print urljoin('http://www.example.com/path/file.html', 'anotherfile.html')
print urljoin('http://www.example.com/path/file.html', '../anotherfile.html')

この例では、そのパスの相対部分("../")は 2番目の URL が算出されるときに考慮されます。

$ python urlparse_urljoin.py
http://www.example.com/path/anotherfile.html
http://www.example.com/anotherfile.html

See also

urlparse
本モジュールの標準ライブラリドキュメント
urllib
URL で識別されるリソースからコンテンツを取り出す
urllib2
リモート URL アクセスの代替 API
Bookmark and Share