urllib2, cookielibを使用し、某管理画面にログインするが
セッションが保持できず、格闘すること数日。。。
苦戦した末、やっと行き着いた答えは
ヘッダが足りなかった事。。。。
keep-aliveという、セッションを保持させる感じの
ブラウザの機能らしいのだが、urllib2には現状では搭載されておらず
Connection: keep-alive
というヘッダは吐き出さない。
んで、付記するように
add_headerやaddheadersなど試みるが、
これはUAしか変更できないのか効果なし。
結局httplibを使用して、無理やりヘッダを作ってあげるしか思いつかなかった。
目的のページへは、ヘッダを吐き出すだけで、簡単にログインに成功した。
Keep-Aliveを保持するには、HTTPConnectionをCloseせずに
そのまま次のリクエストを送信するだけでいい。
ただし、リクエストした後には、
必ずread()を実行しなければエラーを吐く。
まぁ、普通ではあまりない仕様だと思うが
cookielibが、うまく挙動しない場合は
ブラウザが吐き出すリクエストヘッダと同じように
変更してみるのも良いだろう。
以下が、そのスクリプト。
amazonはPOST後にリダイレクトはないが
ログイン等でリダイレクトさせられる場合は、
r.getheader('Location')で、リダイレクト先のURLを
取得し、更にGETでリクエストしなくてはならない。
面倒だが、自動で飛んでしまうより便利だと思う。
# -*- coding: utf-8 -*-import urllib, httplib, re
host = 'www.amazon.co.jp'
path = '/s/'postdata = {}
postdata['__mk_ja_JP'] = 'カタカナ'
postdata['initialSearch'] = 1
postdata['url'] = 'search-alias'
postdata['field-keywords'] = 'python'
postdata['Go'] = 'Go'# PostするデータをURLエンコード
params = urllib.urlencode(postdata)# RequestするHeaderを辞書に定義
headers = {
"Content-type": "application/x-www-form-urlencoded",
'Connection': 'keep-alive',
"Accept": "text/plain"
}# サーバに接続
con = httplib.HTTPConnection(host)# パラメタとヘッダを持って、リクエスト1回目
con.request("POST", path, params, headers)
r = con.getresponse()# ソースを取得(接続は閉じない)
r.read()# クッキーを取得(超適当)
c = r.getheader('Set-Cookie')
c = re.sub(";.*", "", c)# リダイレクトされる場合にはpathをリダイレクト先に変更
# path = r.getheader('Location')# クッキーをヘッダにセット
headers = {
"Content-type": "application/x-www-form-urlencoded",
'Connection': 'keep-alive',
'Cookie': c,
"Accept": "text/plain"
}# 接続を保ったまま、2度目のリクエスト
con.request("POST", path, params, headers)
r = con.getresponse()# ソースを表示
print r.read()# 接続を解除
r.close()

コメントする