Pythonには「後方互換性を大切にする」というモットーがあって,時にはそれが裏目に出ることがある。PythonでWebにリクエストを送る時の手法は,目的に応じて複数存在するが,これも後方互換性を守るがために起こっている現象といえる。当初はシンプルな機能を持つモジュールが利用されていて,その後より高度な機能を持つモジュールが追加されたのだが,後方互換性を守るために古いモジュールが残されているのだ。
たとえば,普通にhtppでGETリクエストを送って結果を取得するなら簡単で
from urllib import urlopen
src = urlopen('http://www.example.com/').read()
とすればよい。
POSTリクエストを送る方法は少しわかりにくくてかつ面倒。パラメータを辞書に入れてurlencode()で加工してやる必要がある
from urllib import urlopen, urlencode
params = {'param1':'foo', 'param2': 'bar'}
urlopen('http://www.example.com/register', urlencode(params))
リクエスト時に独自のヘッダを付けたくなったらどうするか。例えばUser-Agentを変えるときには,urllibではダメなのでより強力なurllib2を使う(他の方法もある)。
import urllib2
request = urllib2.Request(http://www.example.com/)
request.add_header('User-Agent','My Sweet Web Robot')
opener = urllib2.build_opener()
body = opener.open(request).read()
urllibに2をつけたモジュール名を見ただけで,まともな神経の持ち主なら嫌な予感がしてくるはずだ。他にもpopen, popen2など数字つきで強さの違うモジュールがPythonにはあるのだが,これではまるでスーパーサイヤ人だ。
前置きが長くなった。
requestsはシンプルな仕様でかつオールインワンな機能を提供しているWebリクエスト用モジュールだ。認証やクッキーにも対応していてなかなかパワフルでもある。「pip requests」とか「easy_install requests」でインストールするだけで使えるようになる。
たとえばGETリクエストを送って結果を取得するにはこんな風にする。
import requests
r = requests.get('http://www.example.com/')
print r.content
GETリクエストを送りたくてget()メソッドを呼んだのだから,POSTはpost()メソッドを使えばいい,と容易に類推できる。同様にput()やdelete(),head()メソッドがある。
r = requests.post('http://www.example.com/register', {'param1':'foo', 'param2': 'bar'})
パラメーターは辞書で直接送ってやれば良く,いちいちエンコードする必要がなくて楽だ。
リクエスト時に独自のヘッダを送りたいときには,引数に辞書で指定するだけ。
r = requests.get('http://www.example.com/', {''User-Agent':'My Sweet Web Robot'})
シンプルだ。
レスポンスのヘッダはレスポンスオブジェクトを使って「r.headers['content-type']」のように取り出せる。urllibの仕様があんまりストレートでないのと対照的だ。urllibの場合,ヘッダは「r.info()['content-typr']」として取得する。ステータスコードは「r.getcode()」。requestsなら「r.status_code」でオッケー。
というように,ほとんど仕様を覚える必要がないほど素直な設計のモジュールで感心する。urllib2やhttplibをラップして機能を提供しているようで,Pure Pythonで書かれているので運用が容易なのもいい。スクレイピングやWebハックの友に活躍してくれそうなモジュールだ。