HTTP系のPOST,プロクシ(Proxy),クッキー(Cookie),ヘッダ書き換えなんかのメモ

大和桜

HTTPリクエストでPOSTを使う方法

import urllib
import urllib2

post_data = {}
post_data['email'] = 'hoge@hoge.com'

# エンコード
en_post_data = urllib.urlencode(post_data)

# リクエスト
r = urllib2.urlopen('http://hoge.com/',en_post_data)	# urllib.urlopenも同じ

# build_openerも同様
opener = urllib2.build_opener()
r = opener.open('http://hoge.com/',en_post_data)

ようするに、urlopen()やopen()の第2パラメタにデータを渡せばPOSTしてくれる。

プロクシ経由でHTTPリクエストを行う方法

ProxyHandlerにプロクシの処理を任せる。

import urllib2

# ローカルマシン内のプロクシ経由、ポートは8888
proxy_handler = urllib2.ProxyHandler({'http':'http://127.0.0.1:8888/'})
opener = urllib2.build_opener( proxy_handler )

r = opener.open('http://hoge.com/') # リクエスト

urllib.urlopen()使った方がたぶん早い(未確認)けど次で出てくるクッキー(Cookie)を利用するためにbuild_opener()を使ってる。

クッキー(Cookie)付きのHTTPリクエストを行う方法

クッキー関係の処理はHTTPCookieProcessorに任せる。

import urllib2
import cookielib
from cookielib import CookieJar, DefaultCookiePolicy

# クッキーの設定
policy = cookielib.DefaultCookiePolicy(
    rfc2965=True, strict_ns_domain=DefaultCookiePolicy.DomainStrict,
		blocked_domains=["ads.net", ".ads.net"])
		
# クッキーオブジェクトの作成
cj = cookielib.CookieJar(policy)

# HTTPCookieProcessorにクッキーの処理を任せる。
opener = urllib2.build_opener( urllib2.HTTPCookieProcessor(cj) )

r = opener.open('http://hoge.com/') # リクエスト

ヘッダ書き換え

HTTPのレスポンスヘッダやリクエストヘッダを書き換える時はurllib2.BaseHandlerから派生したクラスを利用する。
以下のソースはHTTPレスポンスコード302の場合に追跡するLocationヘッダの値がhttp://hoge.com/だった場合にhttp://hage.com/に書き換えるもの。サーバが302を返した場合、opener.open()内で302に対応する処理が行われてしまうので、その前に書き換える必要がある。

import urllib2

# HTTPレスポンスヘッダのLocationの値を書き換えるクラス
# ただし、HTTPレスポンスコードの値はチェックしていない。
class LocationChangeHandler(urllib2.BaseHandler) :
#	# リクエスト時にヘッダを弄る(今回は実装しない)
#	def http_request(self,req):
#		return req

	# レスポンスを弄る。
	def http_response(self,req,response):
		# ヘッダを書き換える。
		headers = response.headers

		# ロケーションヘッダの書き換え
		if headers.has_key('Location') :
			value = headers['Location']
			headers['Location'] = value.replace('hoge.com','hage.com') # 
		return response

# build_openerでヘッダを書き換えるクラスを指定する。
opener = urllib2.build_opener( LocationChangeHandler() )

r = opener.open('http://hoge.com/fuga.pl') # リクエスト
# http://hoge.com/fuga.plへのリクエストで302レスポンス、http://hoge.com/へのリダイレクトが返ってきた場合、http://hage.com/に対してopener.open()がリクエストを行う。

複合

クッキーを使いながら、プロクシも通して、さらにヘッダーを書き換える場合。さらにPOSTで。

import urllib
import urllib2
import cookielib
from cookielib import CookieJar, DefaultCookiePolicy


# クッキー関連
policy = cookielib.DefaultCookiePolicy(
    rfc2965=True, strict_ns_domain=DefaultCookiePolicy.DomainStrict,
		blocked_domains=["ads.net", ".ads.net"])
cj = cookielib.CookieJar(policy)

# プロクシ
proxy_handler = urllib2.ProxyHandler({'http':'http://127.0.0.1:8888/'})

# ヘッダ書き換え
# LocationChangeHandlerに関しては上のソースを参照されたい。

# プロクシ
proxy_handler = urllib2.ProxyHandler({'http':'http://127.0.0.1:8888/'})

# プロクシ、ヘッダ書き換え、クッキー処理を行うopenerオブジェクトを生成
# 以後、openerオブジェクトを利用することで、上記の機能が利用できる。
opener = urllib2.build_opener( LocationChangeHandler() , proxy_handler , urllib2.HTTPCookieProcessor(cj) )


# POSTするデータ
# en_post_dataに関しても上の方のソースを参照されたい。

# リクエスト
r = opener.open('http://hoge.com/',en_post_data)

build_opener()に複数のBaseHandler派生クラスを渡す所が味噌。