ひきメモ

2007-12-31

[]urllib2モジュール

Getリクエスト

>>> import urllib2
>>> r = urllib2.urlopen("http://www.yahoo.co.jp")

Postリクエスト

>>> import urllib
>>> query = {"name":name, "password":password} # 送信するデータ
>>> query = urllib.urlencode(query )           # URLエンコード
>>> r = urllib2.urlopen("http://www.hatena.ne.jp/login", query)

レスポンスオブジェクトのメソッド

>>> r = urllib2.urlopen("http://d.hatena.ne.jp/yumimue/edit")
>>> r.code, r.msg         # レスポンスコードとメッセージ
(200, 'OK')
>>> r.geturl()            # 取得したリソースのURLを返す
'http://d.hatena.ne.jp/yumimue/'
>>> r.info()              # ヘッダオブジェクトを返す
<httplib.HTTPMessage instance at 0x00DD7A80>
>>> r.geturl()            # 取得したデータのURLを返す
'http://d.hatena.ne.jp/yumimue/'
>>> r.info()              # ヘッダオブジェクトを返す
<httplib.HTTPMessage instance at 0x00DD7A80>
>>>
>>> body = r.read()       # データを全て読み込む
>>> r.read(50)            # 50バイトのデータを読み込む
''
>>> r.readline()          # 1行分のデータを読み込む
''
>>> r.readlines()         # 各行をリストにして読み込む
[]

geturl( )はリダイレクト先のURLが知りたい場合に使います。また、Fileオブジェクトと違いファイルポインタを戻すことはできませんので、一度読み込んだデータを再び読み込むことはできません。上記のようにread( )の後にreadline( )やreadlines( )を呼び出しても無意味です。


レスポンスヘッダを取り出す

>>> r = urllib2.urlopen("http://www.hatena.ne.jp/login",
...      urllib.urlencode({"name":name, "password":password}))
>>> headers = r.info()
>>> headers.getheaders("set-cookie")    # リストで取得
['rk=b1ab4aa8f986f75d6398e92d836e; domain=.hatena.ne.jp; path=/']
>>> headers.getheader("content-length") # 文字列で取得
'20227'
>>> headers.getheader("hoge", "0")  # ヘッダがなければデフォルト値を返す
'0'

ヘッダの値は文字列なので、デフォルト値も文字列にしておいた方がよいと思います。


リクエストヘッダを追加する

urllib.urlopen( )に文字列ではなく、Requestオブジェクトを渡します。

>>> req = urllib2.Request("http://d.hatena.ne.jp/yumimue/edit")
>>> req.add_header("Cookie", cookie)
>>> r = urllib2.urlopen(req)
>>> r.geturl()
'http://d.hatena.ne.jp/yumimue/edit'
>>>
>>> req = urllib2.Request("http://d.hatena.ne.jp/yumimue/edit",
...                        headers={"Cookie":cookie})
>>> r = urllib2.urlopen(req)
>>> r.geturl()
'http://d.hatena.ne.jp/yumimue/edit'

ヘッダをリダイレクト先に送信したくない場合は、add_unredirected_header( )を使います。


例外

>>> urls = ("http://ww.yahoo.co.jp",
...         "http://www.yahoo.co.jp/i.htm",
...         "http://www.yahoo.co.jp/index.html")
>>> for url in urls:
...     try:
...         r = urllib2.urlopen(url)
...         r.code, r.msg
...     except urllib2.HTTPError, e:
...         e.code, e.msg
...     except urllib2.URLError, e: # サーバに接続できない場合に発生
...         e
...
URLError(gaierror(11001, 'getaddrinfo failed'),)
(404, 'Not Found')
(200, 'OK')

HTTPErrorはURLErrorのサブクラスです。また、HTTPErrorクラスの例外オブジェクトはレスポンスオブジェクトと同じように扱うことができます。