20.6. "urllib2" --- URL を開くための拡張可能なライブラリ
********************************************************

注釈: "urllib2" モジュールは、Python 3 で "urllib.request",
  "urllib.error" に分割されました。 *2to3* ツールが自動的にソースコー
  ドのimportを修正 します。

"urllib2" モジュールは基本的な認証、暗号化認証、リダイレクション、クッ
キー、その他の介在する複雑なアクセス環境において (大抵は HTTP で)  URL
を開くための関数とクラスを定義します。

参考: より高水準の HTTP クライアントインターフェイスとしては
  Requests package がお奨めです。

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

urllib2.urlopen(url[, data[, timeout[, cafile[, capath[, cadefault[, context]]]]])

   URL *url* を開きます。 *url* は文字列でも "Request" オブジェクトで
   もかまいません。

   *data* はサーバに送信する追加のデータを示す文字列か、そのようなデー
   タが無ければ *None* を指定します。現時点でHTTPリクエストは *data*
   をサポートする唯一のリクエスト形式です; *data* パラメタが指定が指定
   された場合、HTTP リクエストは GET でなく POST になります。 *data*
   は標準的な *application/x-www-form-urlencoded* 形式のバッファでなく
   てはなりません。 "urllib.urlencode()" 関数はマップ型か2タプルのシー
   ケンスを取り、この形式の文字列を返します。 urllib2 モジュールは
   HTTP/1.1 リクエストを *Connection:close* ヘッダ付きで送信します。

   オプションの *timeout* 引数は、接続開始などのブロックする操作におけ
   るタイムアウト時間を秒数で指定します。 (指定されなかった場合、グロ
   ーバルのデフォルトタイムアウト時間が利用されます) この引数は、
   HTTP, HTTPS, FTP 接続でのみ有効です。

   *context* を指定する場合、 "ssl.SSLContext" インスタンスでなければ
   なりません。それはさまざまな SSL オプションを記述しています。詳細は
   "HTTPSConnection" を参照してください。

   任意のパラメーター *cafile* および *capath* には HTTPS リクエストの
   ための CA 証明書のセットを指定します。*cafile* には CA 証明書のリス
   トを含む 1 個のファイルを指定し、*capath* にはハッシュ化された証明
   書ファイルが格納されたディレクトリを指定しなければなりません。より
   詳しい情報は "ssl.SSLContext.load_verify_locations()" を参照してく
   ださい。

   *cadefault* パラメータは無視されます。

   この関数は以下の 3 つのメソッドを持つファイル類似のオブジェクトを返
   します:

   * "geturl()" --- 取得されたリソースの URL を返します。 主に、リダ
     イ レクトが発生したかどうかを確認するために利用します。

   * "info()" --- 取得されたページのヘッダーなどのメタ情報を、
     "mimetools.Message" インスタンスとして返します。 (Quick Reference
     to HTTP Headers を参照してください)

   * "getcode()" --- レスポンスの HTTP ステータスコードを返します。

   エラーが発生した場合 "URLError" を送出します。

   どのハンドラもリクエストを処理しなかった場合には "None" を返すこと
   があるので注意してください (デフォルトでインストールされる グローバ
   ルハンドラの "OpenerDirector" は、 "UnknownHandler" を使って上記の
   問題が起きないようにしています)。

   さらに、プロキシ設定が検出された場合(例えば "http_proxy" のような
   "*_proxy" 環境変数がセットされているなど)には "ProxyHandler" がデフ
   ォルトでインストールされ、これがプロキシを通してリクエストを処理す
   るようにしています。

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

   バージョン 2.7.9 で変更: *cafile*, *capath*, *cadefault*, *context*
   が追加されました。

urllib2.install_opener(opener)

   指定された "OpenerDirector" のインスタンスを、デフォルトで利用され
   るグローバルの opener としてインストールします。 opener のインスト
   ールは、 urlopen にその opener を使って欲しいとき以外必要ありません
   。普段は単に "urlopen()" の代わりに "OpenerDirector.open()" を利用
   してください。 この関数は引数が本当に "OpenerDirector" のインスタン
   スであるかどうかはチェックしません。適切なインタフェースを持った任
   意のクラスを利用することができます。

urllib2.build_opener([handler, ...])

   与えられた順番に URL ハンドラを連鎖させる "OpenerDirector"  のイン
   スタンスを返します。 *handler* は "BaseHandler" または
   "BaseHandler" のサブクラスのインスタンスのどちらかです (どちらの場
   合も、コンストラクトは引数無しで呼び出せるようになっていなければな
   りません) 。クラス  "ProxyHandler" (proxy 設定が検出された場合),
   "UnknownHandler", "HTTPHandler", "HTTPDefaultErrorHandler",
   "HTTPRedirectHandler", "FTPHandler", "FileHandler",
   "HTTPErrorProcessor" については、そのクラスのインスタンスか、そのサ
   ブクラスのインスタンスが *handler*  に含まれていない限り、
   *handler* よりも先に連鎖します。

   Python が SSL をサポートするように設定してインストールされている場
   合 (すなわち、 "ssl" モジュールを import できる場合) "HTTPSHandler"
   も追加されます。

   Python 2.3 からは、 "BaseHandler" サブクラスでも  "handler_order"
   メンバ変数を変更して、ハンドラリスト内での場所を変更できるようにな
   りました。

状況に応じて、以下の例外が送出されます:

exception urllib2.URLError

   ハンドラが何らかの問題に遭遇した場合、この例外 (またはこの例外から
   派生した例外)を送出します。この例外は "IOError" のサブクラスです。

   reason

      このエラーの原因。メッセージ文字列か、他の例外のインスタンス(リ
      モートURLの場合は "socket.error", ローカルURLの場合は "OSError")
      。

exception urllib2.HTTPError

   これは例外("URLError" のサブクラス)ですが、このオブジェクトは例外で
   ないファイル類似のオブジェクトとして返り値に使うことができます
   ("urlopen()" が返すのと同じものです)。 この機能は、例えばサーバから
   の認証リクエストのように、変わった HTTP エラーを処理するのに役立ち
   ます。

   code

      RFC 2616 に定義されているHTTPステータスコード。 この数値型の値は
      、 "BaseHTTPServer.BaseHTTPRequestHandler.responses" の辞書に登
      録されているコードに対応します。

   reason

      このエラーの理由。メッセージ文字列あるいは他の例外インスタンスで
      す。

以下のクラスが提供されています:

class urllib2.Request(url[, data][, headers][, origin_req_host][, unverifiable])

   このクラスは URL リクエストを抽象化したものです。

   *url* は有効な URL を指す文字列でなくてはなりません。

   *data* はサーバに送信する追加のデータを示す文字列か、そのようなデー
   タが無ければ *None* を指定します。現時点でHTTP リクエストは *data*
   をサポートする唯一のリクエスト形式です; *data* パラメタが指定が指定
   された場合、HTTP リクエストは GET でなく POST になります。 *data*
   は標準的な *application/x-www-form-urlencoded* 形式のバッファでなく
   てはなりません。 "urllib.urlencode()" 関数はマップ型か2タプルのシー
   ケンスを取り、この形式の文字列を返します。

   *headers* は辞書である必要があり、辞書のそれぞれのキーと値を引数と
   して "add_header()" を呼び出したのと同じように扱われます。 この引数
   は、多くの場合ブラウザーが何であるかを特定する "User-Agent" ヘッダ
   ーの値を "偽装" するために用いられます。 これは一部の HTTP サーバー
   が、スクリプトからのアクセスを禁止するために一般的なブラウザーの
   "User-Agent" ヘッダーしか許可しないためです。 例えば、 Mozilla
   Firefox は "User-Agent" に ""Mozilla/5.0 (X11; U; Linux i686)
   Gecko/20071127 Firefox/2.0.0.11"" のように設定し、 "urllib2" はデフ
   ォルトで ""Python-urllib/2.6"" (Python 2.6の場合) と設定します。

   最後の二つの引数は、サードパーティの HTTP クッキーを正しく扱いたい
   場合にのみ関係してきます:

   *origin_req_host* は、 **RFC 2965** で定義されている元のトランザク
   ションにおけるリクエストホスト (request-host of the origin
   transaction) です。デフォルトの値は "cookielib.request_host(self)"
   です。 この値は、ユーザによって開始された元々のリクエストにおけるホ
   スト名や IP アドレスです。例えば、もしリクエストがある HTML ドキュ
   メント内の画像を指していれば、この値は画像を含んでいるページへのリ
   クエストにおけるリクエストホストになるはずです。

   *unverifiable* は、 **RFC 2965** の定義において、該当するリクエスト
   が証明不能 (unverifiable) であるかどうかを示します。デフォルトの値
   は "False" です。証明不能なリクエストとは、ユーザが受け入れの可否を
   選択できないような URL を持つリクエストのことです。例えば、リクエス
   トが HTML ドキュメント中の画像であり、ユーザがこの画像を自動的に取
   得するか どうかを選択できない場合には、証明不能フラグは True になり
   ます。

class urllib2.OpenerDirector

   "OpenerDirector" クラスは、 "BaseHandler" の連鎖的に呼び出して URL
   を開きます。このクラスはハンドラをどのように連鎖させるか、またどの
   ようにエラーをリカバリするかを管理します。

class urllib2.BaseHandler

   このクラスはハンドラ連鎖に登録される全てのハンドラがベースとしてい
   るクラスです -- このクラスでは登録のための単純なメカニズムだけを扱
   います。

class urllib2.HTTPDefaultErrorHandler

   HTTP エラー応答のための標準のハンドラを定義します; 全てのレスポンス
   に対して、例外 "HTTPError" を送出します。

class urllib2.HTTPRedirectHandler

   リダイレクションを扱うクラスです。

class urllib2.HTTPCookieProcessor([cookiejar])

   HTTP Cookie を扱うためのクラスです。

class urllib2.ProxyHandler([proxies])

   このクラスはプロキシを通過してリクエストを送らせます。引数
   *proxies* を与える場合、プロトコル名からプロキシの URL へ対応付ける
   辞書でなくてはなりません。標準では、プロキシのリストを環境変数
   "<protocol>_proxy"  から読み出します。プロキシ環境変数が設定されて
   いない場合は、 Windows 環境では、 レジストリのインターネット設定セ
   クションからプロキシ設定を手に入れ、 Mac OS X 環境では、 OS X シス
   テム設定フレームワーク (System Configuration Framework) からプロキ
   シ情報を取得します。

   自動検出されたproxyを無効にするには、空の辞書を渡してください。

      注釈: 変数 "REQUEST_METHOD" が設定されている場合、
        "HTTP_PROXY" は無 視されます; "getproxies()" のドキュメンテー
        ションを参照してく ださい。

class urllib2.HTTPPasswordMgr

   "(realm, uri) -> (user, password)" の対応付けデータベースを保持しま
   す。

class urllib2.HTTPPasswordMgrWithDefaultRealm

   "(realm, uri) -> (user, password)"  の対応付けデータベースを保持し
   ます。レルム "None" はその他諸々のレルムを表し、他のレルムが該当し
   ない場合に検索されます。

class urllib2.AbstractBasicAuthHandler([password_mgr])

   このクラスはHTTP 認証を補助するための混ぜ込みクラス (mixin class)
   です。遠隔ホストとプロキシの両方に対応しています。 *password_mgr*
   を与える場合、 "HTTPPasswordMgr" と互換性がなければなりません; 互換
   性のためにサポートしなければならないインタフェースについての情報は
   セクション HTTPPasswordMgr オブジェクト を参照してください。

class urllib2.HTTPBasicAuthHandler([password_mgr])

   遠隔ホストとの間での認証を扱います。 *password_mgr* を与える場合、
   "HTTPPasswordMgr" と互換性が なければなりません;  互換性のためにサ
   ポートしなければならないインタフェースについての情報はセクション
   HTTPPasswordMgr オブジェクト を参照してください。

class urllib2.ProxyBasicAuthHandler([password_mgr])

   プロキシとの間での認証を扱います。 *password_mgr* を与える場合、
   "HTTPPasswordMgr" と互換性が なければなりません;  互換性のためにサ
   ポートしなければならないインタフェースについての情報はセクション
   HTTPPasswordMgr オブジェクト を参照してください。

class urllib2.AbstractDigestAuthHandler([password_mgr])

   このクラスはHTTP 認証を補助するための混ぜ込みクラス (mixin class)
   です。遠隔ホストとプロキシの両方に対応しています。 *password_mgr*
   を与える場合、 "HTTPPasswordMgr" と互換性がなければなりません; 互換
   性のためにサポートしなければならないインタフェースについての情報は
   セクション HTTPPasswordMgr オブジェクト を参照してください。

class urllib2.HTTPDigestAuthHandler([password_mgr])

   遠隔ホストとの間での認証を扱います。 *password_mgr* を与える場合、
   "HTTPPasswordMgr" と互換性が なければなりません;  互換性のためにサ
   ポートしなければならないインタフェースについての情報はセクション
   HTTPPasswordMgr オブジェクト を参照してください。

class urllib2.ProxyDigestAuthHandler([password_mgr])

   プロキシとの間での認証を扱います。 *password_mgr* を与える場合、
   "HTTPPasswordMgr" と互換性が なければなりません;  互換性のためにサ
   ポートしなければならないインタフェースについての情報はセクション
   HTTPPasswordMgr オブジェクト を参照してください。

class urllib2.HTTPHandler

   HTTP の URL を開きます。

class urllib2.HTTPSHandler([debuglevel[, context]])

   HTTPS の URL のオープンを処理するクラスです。 *context* は
   "httplib.HTTPSConnection" のものと同じです。

   バージョン 2.7.9 で変更: *context* が追加されました。

class urllib2.FileHandler

   ローカルファイルを開きます。

class urllib2.FTPHandler

   FTP の URL を開きます。

class urllib2.CacheFTPHandler

   FTP の URL を開きます。遅延を最小限にするために、開かれている FTP
   接続に対するキャッシュを保持します。

class urllib2.UnknownHandler

   その他諸々のためのクラスで、未知のプロトコルの URL を開きます。

class urllib2.HTTPErrorProcessor

   HTTP エラー応答の処理をします。


20.6.1. Request オブジェクト
============================

以下のメソッドは "Request" の全ての公開インタフェースを記述します。 従
ってサブクラスではこれら全てのメソッドをオーバライドしなければなりませ
ん。

Request.add_data(data)

   "Request" のデータを *data* に設定します。この値は HTTP  ハンドラ以
   外のハンドラでは無視されます。HTTP ハンドラでは、データはバイト文字
   列でなくてはなりません。このメソッドを使うとリクエストの形式が
   "GET" から "POST" に変更されます。

Request.get_method()

   HTTP リクエストメソッドを示す文字列を返します。このメソッドは HTTP
   リクエストだけに対して意味があり、現状では常に "'GET'" か "'POST'"
   のいずれかの値を返します。

Request.has_data()

   インスタンスが "None" でないデータを持つかどうかを返します。

Request.get_data()

   インスタンスのデータを返します。

Request.add_header(key, val)

   リクエストに新たなヘッダを追加します。ヘッダは HTTP ハンドラ以外の
   ハンドラでは無視されます。HTTP ハンドラでは、引数はサーバに送信され
   る ヘッダのリストに追加されます。同じ名前を持つヘッダを 2 つ以上持
   つことはできず、 *key* の衝突が生じた場合、後で追加したヘッダが前に
   追加したヘッダを上書きします。現時点では、この機能は HTTP の機能を
   損ねることはありません。というのは、複数回呼び出したときに意味を 持
   つようなヘッダには、どれもただ一つのヘッダを使って同じ機能を果たす
   ための (ヘッダ特有の) 方法があるからです。

Request.add_unredirected_header(key, header)

   リダイレクトされたリクエストには追加されないヘッダを追加します。

   バージョン 2.4 で追加.

Request.has_header(header)

   インスタンスが名前つきヘッダであるかどうかを (通常のヘッダと非リダ
   イレクトヘッダの両方を調べて) 返します。

   バージョン 2.4 で追加.

Request.get_full_url()

   コンストラクタで与えられた URL を返します。

Request.get_type()

   URL のタイプ --- いわゆるスキーム (scheme) --- を返します。

Request.get_host()

   接続を行う先のホスト名を返します。

Request.get_selector()

   セレクタ --- サーバに送られる URL の一部分 --- を返します。

Request.get_header(header_name, default=None)

   指定されたヘッダの値を返します。ヘッダがない場合は、 *default* の値
   を返します。

Request.header_items()

   リクエストヘッダの値を、タプル (header_name, header_value) のリスト
   で返します。

Request.set_proxy(host, type)

   リクエストがプロキシサーバを経由するように準備します。 *host* およ
   び *type* はインスタンスのもとの設定と置き換えられ ます。インスタン
   スのセレクタはコンストラクタに与えたもともとの URL になります。

Request.get_origin_req_host()

   **RFC 2965** の定義よる、始原トランザクションのリクエストホストを返
   します。 "Request" コンストラクタのドキュメントを 参照してください
   。

Request.is_unverifiable()

   リクエストが **RFC 2965** の定義における証明不能リクエストであるか
   どうかを返します。 "Request" コンストラクタのドキュメントを参照して
   ください。


20.6.2. OpenerDirector オブジェクト
===================================

"OpenerDirector" インスタンスは以下のメソッドを持っています:

OpenerDirector.add_handler(handler)

   *handler* は "BaseHandler" のインスタンスでなければなりません。以下
   のメソッドを使った検索が行われ、URL を取り扱うことが可能なハンドラ
   の連鎖が追加されます (HTTP エラーは特別扱いされているので注意してく
   ださい)。

   * "*protocol*_open" --- ハンドラが *protocol* の URL を開く方法を
     知 っているかどうかを調べます。

   * "http_error_*type*" --- ハンドラが HTTP エラーコード *type* の
     処 理方法を知っていることを示すシグナルです。

   * "*protocol*_error" --- ハンドラが ("http" でない) *protocol* の
     エ ラー を処理する方法を知っていることを示すシグナルです。

   * "*protocol*_request" --- ハンドラが *protocol* リクエストのプリ
     プ ロセス方法 を知っていることを示すシグナルです。

   * "*protocol*_response" --- ハンドラが *protocol* リクエストのポ
     ス トプロセス方法 を知っていることを示すシグナルです。

OpenerDirector.open(url[, data][, timeout])

   与えられた *url* (リクエストオブジェクトでも文字列でもかまいません)
   を開きます。オプションとして *data* を与えることができます。 引数、
   返り値、および送出される例外は "urlopen()" と同じです ("urlopen()"
   の場合、標準でインストールされている グローバルな "OpenerDirector"
   の "open()" メソッドを呼び出します) 。 オプションの *timeout* 引数
   は、接続開始のようなブロックする処理におけるタイムアウト時間を 秒数
   で指定します。(指定しなかった場合は、グローバルのデフォルト設定が利
   用されます) タイムアウト機能は、 HTTP, HTTPS, FTP 接続でのみ有効で
   す。

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

OpenerDirector.error(proto[, arg[, ...]])

   与えられたプロトコルにおけるエラーを処理します。このメソッドは与え
   られたプロトコルにおける登録済みのエラーハンドラを (プロトコル固有
   の) 引数で呼び出します。 HTTP プロトコルは特殊なケースで、特定のエ
   ラーハンドラを選び出すのに HTTP レスポンスコードを使います; ハンド
   ラクラスの "http_error_*()" メソッドを参照してください。

   返り値および送出される例外は "urlopen()" と同じものです。

OpenerDirector オブジェクトは、以下の 3 つのステージに分けて URL を開
きます:

各ステージで OpenerDirector オブジェクトのメソッドがどのような順で呼び
出されるかは、ハンドラインスタンスの並び方で決まります。

1. "*protocol*_request" 形式のメソッドを持つ全てのハンドラに対して
   その メソッドを呼び出し、リクエストの プリプロセスを行います。

2. "*protocol*_open" 形式のメソッドを持つハンドラを呼び出し、リクエ
   ス トを処理します。 このステージは、ハンドラが "None" でない値 (す
   なわ ちレスポンス) を返すか、例外 (通常は "URLError") を送出した時
   点で終 了します。例外は伝播 (propagate) できます。

   実際には、上のアルゴリズムではまず "default_open()" という名前のメ
   ソッドを呼び出します。このメソッドが全て "None" を返す場合、同じア
   ルゴリズムを繰り返して、今度は "*protocol*_open" 形式のメソッドを試
   します。メソッドが全て "None" を返すと、さらに同じアルゴリズムを繰
   り返して "unknown_open()" を呼び出します。

   これらのメソッドの実装には、親となる "OpenerDirector" インスタンス
   の "open()" や "error()" といったメソッド呼び出しが入る場合があるの
   で注意してください。

3. "*protocol*_response" 形式のメソッドを持つ全てのハンドラに対して
   そ のメソッドを呼び出し、リクエストの ポストプロセスを行います。


20.6.3. BaseHandler オブジェクト
================================

"BaseHandler" オブジェクトは直接的に役に立つ 2 つのメソッドと、その他
として派生クラスで使われることを想定したメソッドを 提供します。以下は
直接的に使うためのメソッドです:

BaseHandler.add_parent(director)

   親オブジェクトとして、 "director" を追加します。

BaseHandler.close()

   全ての親オブジェクトを削除します。

以下の属性およびメソッドは "BaseHandler" から派生したクラスでのみ使わ
れます:

注釈: 慣習的に、 "protocol_request()" や "protocol_response()" とい
  ったメ ソッドを定義している サブクラスは "*Processor" と名づけ、その
  他は "* Handler" と名づけることになっています

BaseHandler.parent

   有効な "OpenerDirector" です。この値は違うプロトコルを使って URL を
   開く場合やエラーを処理する際に使われます。

BaseHandler.default_open(req)

   このメソッドは "BaseHandler" では定義されて *いません* 。しかし、全
   ての URL をキャッチさせたいなら、サブクラスで定義する 必要がありま
   す。

   このメソッドが定義されていた場合、 "OpenerDirector" から呼び出され
   ます。このメソッドは "OpenerDirector" のメソッド "open()" が返す値
   について記述されているようなファイル類似の オブジェクトか、 "None"
   を返さなくてはなりません。このメソッドが送出する例外は、真に例外的
   なことが起きない限り、 "URLError" を送出しなければなりません (例え
   ば、 "MemoryError" を "URLError" をマップしてはいけません)。

   このメソッドはプロトコル固有のオープンメソッドが呼び出される前に呼
   び出されます。

BaseHandler.protocol_open(req)

   ("protocol" は実際にはプロトコル名です)

   このメソッドは "BaseHandler" では定義されて *いません* 。しかし
   *protocol* の URL をキャッチしたいなら、サブクラスで定義する必要が
   あります。

   このメソッドが定義されていた場合、 "OpenerDirector" から呼び出され
   ます。戻り値は "default_open()" と同じでなければなりません。

BaseHandler.unknown_open(req)

   このメソッドは "BaseHandler" では定義されて *いません* 。しかし URL
   を開くための特定のハンドラが登録されていないような URL をキャッチし
   たいなら、サブクラスで定義する必要があります。

   このメソッドが定義されていた場合、 "OpenerDirector" から呼び出され
   ます。戻り値は "default_open()" と同じでなければなりません。

BaseHandler.http_error_default(req, fp, code, msg, hdrs)

   このメソッドは "BaseHandler" では定義されて *いません* 。しかしその
   他の処理されなかった HTTP エラーを処理する機能をもたせたいなら、サ
   ブクラスで定義する必要があります。このメソッドはエラーに遭遇した
   "OpenerDirector" から自動的に呼び出されます。その他の状況では普通呼
   び出すべきではありません。

   *req* は "Request" オブジェクトで、 *fp* は HTTP エラー本体を読み出
   せるようなファイル類似のオブジェクトに なります。 *code* は 3 桁の
   10 進数からなるエラーコードで、 *msg* ユーザ向けのエラーコード解説
   です。 *hdrs* は エラー応答のヘッダをマップしたオブジェクトです。

   返される値および送出される例外は "urlopen()" と同じものでなければな
   りません。

BaseHandler.http_error_nnn(req, fp, code, msg, hdrs)

   *nnn* は 3 桁の 10 進数からなる HTTP エラーコードでなくてはなりませ
   ん。このメソッドも "BaseHandler" では定義されていませんが、サブクラ
   スのインスタンスで定義されていた場合、エラーコード *nnn* の HTTP エ
   ラーが発生した際に呼び出されます。

   特定の HTTP エラーに対する処理を行うためには、このメソッドをサブク
   ラスでオーバライドする必要があります。

   引数、返される値、および送出される例外は "http_error_default()" と
   同じものでなければなりません。

BaseHandler.protocol_request(req)

   ("protocol" は実際にはプロトコル名です)

   このメソッドは "BaseHandler" では *定義されていません* が、サブクラ
   スで特定の *protocol* のリクエストのプリプロセスを行いたい場合には
   定義する必要があります。

   このメソッドが定義されていると、親となる "OpenerDirector" から呼び
   出されます。その際、 *req* は "Request" オブジェクトになります。戻
   り値は "Request" オブジェクトでなければなりません。

BaseHandler.protocol_response(req, response)

   ("protocol" は実際にはプロトコル名です)

   このメソッドは "BaseHandler" では *定義されていません* が、サブクラ
   スで特定の *protocol* のリクエストのポストプロセスを行いたい場合に
   は定義する必要があります。

   このメソッドが定義されていると、親となる "OpenerDirector" から呼び
   出されます。その際、 *req* は "Request" オブジェクトになります。
   *response* は "urlopen()" の戻り値と同じインタフェースを 実装したオ
   ブジェクトになります。戻り値もまた、 "urlopen()" の戻り値と同じイン
   タフェースを実装したオブジェクトでなければなりません。


20.6.4. HTTPRedirectHandler オブジェクト
========================================

注釈: HTTP リダイレクトによっては、このモジュールのクライアントコー
  ド側で の処理を必要とします。その場合、 "HTTPError" が送出されます。
  様々な リダイレクトコードの厳密な意味に関する詳細は **RFC 2616** を
  参照して ください。

HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)

   リダイレクトの通知に応じて、 "Request" または "None" を返します。こ
   のメソッドは "http_error_30*()" メソッドにおいて、リダイレクトの通
   知をサーバから受信した際に、デフォルトの実装として呼び出されます。
   リダイレクトを起こす場合、新たな "Request" を生成して、
   "http_error_30*()" が *newurl* へリダイレクトを実行できるようにしま
   す。 そうでない場合、他のどのハンドラにもこの URL を処理させたくな
   ければ "HTTPError" を送出し、 リダイレクト処理を行うことはできない
   が他のハンドラなら可能かもしれない場合には "None" を返します。

   注釈: このメソッドのデフォルトの実装は、 **RFC 2616** に厳密に従
     ったも のではありません。 **RFC 2616** では、 "POST" リクエストに
     対する 301 および 302 応答が、ユーザの承認なく自動的にリダイレク
     トされて はならないと述べています。現実には、ブラウザは POST を
     "GET" に変 更することで、これらの応答に対して自動的にリダイレクト
     を行えるよ うにしています。デフォルトの実装でも、この挙動を再現し
     ています。

HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)

   "Location:" か "URI:" のURL にリダイレクトします。このメソッドは
   HTTP  における 'moved permanently' レスポンスを取得した際に 親オブ
   ジェクトとなる "OpenerDirector" によって呼び出されます。

HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)

   "http_error_301()" と同じですが、'found' レスポンスに対して呼び出さ
   れます。

HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)

   "http_error_301()" と同じですが、'see other' レスポンスに対して呼び
   出されます。

HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)

   "http_error_301()" と同じですが、'temporary redirect'  レスポンスに
   対して呼び出されます。


20.6.5. HTTPCookieProcessor オブジェクト
========================================

バージョン 2.4 で追加.

"HTTPCookieProcessor" インスタンスは属性をひとつだけ持ちます:

HTTPCookieProcessor.cookiejar

   クッキーの入っている "cookielib.CookieJar" オブジェクトです。


20.6.6. ProxyHandler オブジェクト
=================================

ProxyHandler.protocol_open(request)

   ("protocol" は実際にはプロトコル名です)

   "ProxyHandler" は、コンストラクタで与えた辞書 *proxies* にプロキシ
   が設定されているような *protocol* 全てについて、メソッド
   "*protocol*_open" を持つことになります。このメソッドは
   "request.set_proxy()" を呼び出して、リクエストがプロキシを通過でき
   るように修正します。その後連鎖するハンドラの中から次のハンドラを呼
   び出して実際にプロトコルを実行します。


20.6.7. HTTPPasswordMgr オブジェクト
====================================

以下のメソッドは "HTTPPasswordMgr" および
"HTTPPasswordMgrWithDefaultRealm" オブジェクトで利用できます。

HTTPPasswordMgr.add_password(realm, uri, user, passwd)

   *uri* は単一の URI でも複数の URI からなるシーケンスでもかまいませ
   ん。 *realm* 、 *user* および *passwd* は文字列でなくてはなりません
   。このメソッドによって、 *realm* と与えられた URI の上位 URI に対し
   て "(user, passwd)" が認証トークンとして使われるようになります。

HTTPPasswordMgr.find_user_password(realm, authuri)

   与えられたレルムおよび URI に対するユーザ名またはパスワードがあれば
   それを取得します。該当するユーザ名／パスワードが存在しない場合、こ
   のメソッドは "(None, None)" を返します。

   "HTTPPasswordMgrWithDefaultRealm" オブジェクトでは、与えられた
   *realm* に対して該当するユーザ名/パスワードが存在しない場合、レルム
   "None" が検索されます。


20.6.8. AbstractBasicAuthHandler オブジェクト
=============================================

AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)

   ユーザ名／パスワードを取得し、再度サーバへのリクエストを試みること
   で、サーバからの認証リクエストを処理します。 *authreq* はリクエスト
   において レルムに関する情報が含まれているヘッダの名前、 *host* は認
   証を行う対象の URL とパスを指定します、 *req* は (失敗した)
   "Request" オブジェクト、そして *headers* はエラーヘッダでなくてはな
   りません。

   *host* は、オーソリティ (例 ""python.org"") か、オーソリティコンポ
   ーネントを含む URL (例 ""http://python.org"") です。どちらの場合も
   、オーソリティはユーザ情報コンポーネントを含んではいけません (なの
   で、 ""python.org"" や ""python.org:80"" は正しく、
   ""joe:password@python.org"" は不正です) 。


20.6.9. HTTPBasicAuthHandler オブジェクト
=========================================

HTTPBasicAuthHandler.http_error_401(req, fp, code, msg, hdrs)

   認証情報がある場合、認証情報付きで再度リクエストを試みます。


20.6.10. ProxyBasicAuthHandler オブジェクト
===========================================

ProxyBasicAuthHandler.http_error_407(req, fp, code, msg, hdrs)

   認証情報がある場合、認証情報付きで再度リクエストを試みます。


20.6.11. AbstractDigestAuthHandler オブジェクト
===============================================

AbstractDigestAuthHandler.http_error_auth_reqed(authreq, host, req, headers)

   *authreq* はリクエストにおいてレルムに関する情報が含まれているヘッ
   ダの名前、 *host* は認証を行う対象のホスト名、 *req* は  (失敗した)
   "Request" オブジェクト、そして *headers* はエラーヘッダでなくてはな
   りません。


20.6.12. HTTPDigestAuthHandler オブジェクト
===========================================

HTTPDigestAuthHandler.http_error_401(req, fp, code, msg, hdrs)

   認証情報がある場合、認証情報付きで再度リクエストを試みます。


20.6.13. ProxyDigestAuthHandler オブジェクト
============================================

ProxyDigestAuthHandler.http_error_407(req, fp, code, msg, hdrs)

   認証情報がある場合、認証情報付きで再度リクエストを試みます。


20.6.14. HTTPHandler オブジェクト
=================================

HTTPHandler.http_open(req)

   HTTP リクエストを送ります。 "req.has_data()" に応じて、 GET または
   POST のどちらでも送ることができます。


20.6.15. HTTPSHandler オブジェクト
==================================

HTTPSHandler.https_open(req)

   HTTPS リクエストを送ります。 "req.has_data()" に応じて、 GET または
   POST のどちらでも送ることができます。


20.6.16. FileHandler オブジェクト
=================================

FileHandler.file_open(req)

   ホスト名がない場合、またはホスト名が "'localhost'" の場合にファイル
   をローカルでオープンします。そうでない場合、プロトコルを "ftp" に切
   り替え、 "parent" を使って再度オープンを試みます。


20.6.17. FTPHandler オブジェクト
================================

FTPHandler.ftp_open(req)

   *req* で表されるファイルを FTP 越しにオープンします。ログインは常に
   空のユーザネームおよびパスワードで行われます。


20.6.18. CacheFTPHandler オブジェクト
=====================================

"CacheFTPHandler" オブジェクトは "FTPHandler" オブジェクトに以下のメソ
ッドを追加したものです:

CacheFTPHandler.setTimeout(t)

   接続のタイムアウトを *t* 秒に設定します。

CacheFTPHandler.setMaxConns(m)

   キャッシュ付き接続の最大接続数を *m* に設定します。


20.6.19. UnknownHandler オブジェクト
====================================

UnknownHandler.unknown_open()

   例外 "URLError" を送出します。


20.6.20. HTTPErrorProcessor オブジェクト
========================================

バージョン 2.4 で追加.

HTTPErrorProcessor.http_response()

   HTTP エラー応答の処理をします。

   エラーコード 200 の場合、レスポンスオブジェクトを即座に返します。

   200 以外のエラーコードの場合、 "OpenerDirector.error()" を介して
   "*protocol*_error_code" メソッドに仕事を引き渡します。最終的にどの
   ハンドラもエラーを処理しなかった 場合、
   "urllib2.HTTPDefaultErrorHandler" が "HTTPError" を送出します。

HTTPErrorProcessor.https_response()

   HTTPS エラー応答の処理をします。

   振る舞いは "http_response()" と同じです。


20.6.21. 例
===========

以下の例の他に urllib2 を使ってインターネット上のリソースを取得するに
は に多くの例があります。

以下の例では、 python.org のメインページを取得して、その最初の 100 バ
イト分を表示します:

   >>> import urllib2
   >>> f = urllib2.urlopen('http://www.python.org/')
   >>> print f.read(100)
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
   <?xml-stylesheet href="./css/ht2html

今度は CGI の標準入力にデータストリームを送信し、CGI が返すデータを読
み出します。この例は Python が SSL をサポートしている場合にのみ 動作す
ることに注意してください。

   >>> import urllib2
   >>> req = urllib2.Request(url='https://localhost/cgi-bin/test.cgi',
   ...                       data='This data is passed to stdin of the CGI')
   >>> f = urllib2.urlopen(req)
   >>> print f.read()
   Got Data: "This data is passed to stdin of the CGI"

上の例で使われているサンプルの CGI は以下のようになっています:

   #!/usr/bin/env python
   import sys
   data = sys.stdin.read()
   print 'Content-type: text-plain\n\nGot Data: "%s"' % data

以下はベーシック HTTP 認証の例です:

   import urllib2
   # Create an OpenerDirector with support for Basic HTTP Authentication...
   auth_handler = urllib2.HTTPBasicAuthHandler()
   auth_handler.add_password(realm='PDQ Application',
                             uri='https://mahler:8092/site-updates.py',
                             user='klem',
                             passwd='kadidd!ehopper')
   opener = urllib2.build_opener(auth_handler)
   # ...and install it globally so it can be used with urlopen.
   urllib2.install_opener(opener)
   urllib2.urlopen('http://www.example.com/login.html')

"build_opener()" はデフォルトで沢山のハンドラを提供しており、その中に
"ProxyHandler" があります。デフォルトでは、 "ProxyHandler" は
"<scheme>_proxy" という環境変数を使います。 ここで "<scheme>" は URL
スキームです。例えば、 HTTP プロキシの URL を得るには、環境変数
"http_proxy" を読み出します。

この例では、デフォルトの "ProxyHandler" を置き換えてプログラム的に作成
したプロキシ URL を使うようにし、 "ProxyBasicAuthHandler" でプロキシ認
証サポートを追加します。

   proxy_handler = urllib2.ProxyHandler({'http': 'http://www.example.com:3128/'})
   proxy_auth_handler = urllib2.ProxyBasicAuthHandler()
   proxy_auth_handler.add_password('realm', 'host', 'username', 'password')

   opener = urllib2.build_opener(proxy_handler, proxy_auth_handler)
   # This time, rather than install the OpenerDirector, we use it directly:
   opener.open('http://www.example.com/login.html')

以下は HTTP ヘッダを追加する例です:

*headers* 引数を使って "Request" コンストラクタを呼び出す方法の他に、
以下のようにできます:

   import urllib2
   req = urllib2.Request('http://www.example.com/')
   req.add_header('Referer', 'http://www.python.org/')
   # Customize the default User-Agent header value:
   req.add_header('User-Agent', 'urllib-example/0.1 (Contact: . . .)')
   r = urllib2.urlopen(req)

"OpenerDirector" は全ての "Request" に *User-Agent* ヘッダを自動的に追
加します。これを変更するには以下のようにします:

   import urllib2
   opener = urllib2.build_opener()
   opener.addheaders = [('User-agent', 'Mozilla/5.0')]
   opener.open('http://www.example.com/')

また、 "Request" が "urlopen()" (や "OpenerDirector.open()")に渡される
際には、いくつかの標準ヘッダ (*Content-Length*, *Content-Type* および
*Host*) も追加されることを忘れないでください。
