2012年5月19日土曜日

[Python]CookieとBasic認証を扱うHTTPクライアントの作り方

■概要
CookieとBasic認証を扱うHTTPクライアントが欲しくてPythonでサクッとつくってみました。
※リクエストURLや設定情報を外部ファイルから読み込むようにすると更に使いやすいですが、それは別の機会に。

■実装
Pythonの標準モジュールであるurllib2、cookielibを使用します。
これらのモジュールはPythonのバージョンが2.4以降であれば、問題なく使用できます。

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import os.path, sys

def sendRequest():

    # urllib2をインポートする。
    from urllib2 import urlopen, Request

    # Basic認証の認証情報を設定
    auth_realm = 'realm'
    auth_host = 'host_name'
    auth_id = 'id'
    auth_pw = 'password'

    # cookieの保持情報を設定する。(下記指定ではカレントディレクトリが保存先と)
    COOKIEFILE = 'cookies.lwp'

    # cookielibモジュールの読み込み
    try:

        import cookielib

    except ImportError:

        cookielib = None

    else:

        # 正常に読み込めた場合、LWPCookieJarクラスのインスタンス化。
        cj = cookielib.LWPCookieJar()

    # URLハンドラをセットアップする。
    if cj is not None:

        if os.path.isfile(COOKIEFILE):

            cj.load(COOKIEFILE)

        if cookielib:

            # Basic認証用にHTTPBasicAuthHandlerクラスをインスタンス化し、認証情報を付与する。
            auth_handler = urllib2.HTTPBasicAuthHandler()
            auth_handler.add_password(auth_realm, auth_host, auth_id, auth_pw)

            opener = urllib2.build_opener(auth_handler,urllib2.HTTPCookieProcessor(cj))
            urllib2.install_opener(opener)
        else:
            print "Sorry, can't cookielib."

    # リクエスト情報を設定する。
    theurl = 'http://www.google.com/'
    txdata = None
    txheaders = {'User-agent': 'something_useragent'}

    # リクエスト情報をもとにRequestクラスをインスタンス化し、リクエストを送信する。
    try:
        req = Request(theurl, txdata, txheaders)
        response = urlopen(req)

    # リクエストエラーの場合、エラー情報を出力する。
    except IOError, e:
        print 'Failed to open "%s".' % theurl
        if hasattr(e, 'code'):
            print 'Error code: "%s".' % e.code

    # レスポンスを出力する。
    else:
        print '===== Here are the request of the page. =====\n'
        print str(url) + '\n'

        print '***** Here are the headers of the page. *****\n'
        print str(response.info()) + '\n'

        print '----- Here are the contents of the page. -----\n'
        print str(response.read()) + '\n'

    # Cookieを保存する。
    if cj is None:
        print "Sorry, no cookie jar."
    else:
        print "Here are the cookies received so far:"

        for index, cookie in enumerate(cj):

            print index, ': ', cookie

        cj.save(COOKIEFILE)

    return 0

if __name__ == "__main__":
    sys.exit(sendRequest())
以上です。

参考URL
http://www.python.jp/doc/2.4/lib/module-urllib2.html
http://www.python.jp/doc/2.4/lib/module-cookielib.html
http://www.python.jp/doc/2.4/lib/file-cookie-jar-classes.html

参考文献
Python クックブック 第2版(O'Reilly Japan)