はじめに
サワディーカップ(こんにちは)、Python界のミステリハンターです。さて、PyCon mini JPから早くも1週間が経ちまして、僕もPythonやってかないといかんなー、と思った次第です。そこで、早速Webクローラーを書きまして、そのときにformデータをmultipartで送信する部分がありましたので、こんな感じに実装したよというのをメモしておきます。
multipart/form-data関連リンク
- RFC 2045 - multipart自体のRFC
- RFC 2388 - Returning Values from Forms: multipart/form-data (RFC2388)
- ISAPI Extension (5) : Multipart/form-data の処理
まあ要はurlencodeで送信してた内容を区切り線で分けてbodyに突っ込みました、ちゃんちゃん、っつーことでいいんすかね。
こんな感じに実装した
urllib2を使ったのはヘッダの追加が簡単だったからです。httplibを使う例が多いですが、やってる内容をみるとurllib2のが楽だったりします。
import urllib2 url = r"http://test.example.com/path/to/form" encoding = "euc-jp" boundary = u"--------python" # formの内容の辞書 form_dict = dict(user=u"hoge", pass=u"日本語もおk") # form_dict辞書内の要素数だけ区切り線で分けたbodyを作る def multipart_formdata(form_dict): disposition = u'Content-Disposition: form-data; name="%s"' lines = [] for k, v in form_dict.iteritems(): lines.append(u'--' + boundary) lines.append(disposition % k) lines.append(u'') lines.append(v) lines.append(u"--" + boundary + u"--") lines.append(u'') value = u"\r\n".join(lines) return value.encode(encoding) # ヘッダにContent-Typeを指定 def request_with_multipart_formdata(): req = urllib2.Request(url) req.add_header("Content-Type", "multipart/form-data; boundary=%s" % boundary.encode(encoding)) data = multipart_formdata(form_dict) conn = urllib2.urlopen(req, data)
これはフォームデータを送るような簡単な場合ですが、画像ファイルなどを送信する場合はもうちょい手が加わります。今回は実装してませんが、ほんのちょっと手を加えるだけです。