概要
urllib では multipart/form-data
を送信するための便利メソッドなどは用意されていません
なので今回は自力で multipart/form-data
のリクエストボディを生成してリクエストしてみました
環境
- macOS 10.15.7
- Python 3.8.5
テキストファイルを送信するサンプル
multipart/form-data
はすごい簡単に説明すると boundary という境界文字で区切った複数のコンテンツを送信する方式です
まずは適当な文字列のフォーム+テキストファイルのフォームを送信してみました
vim text_file_test.py
import urllib
import urllib.request
url = "http://localhost:8080/upload"
encoding = "utf-8"
boundary = "--------python"
def multipart_formdata():
lines = []
lines.append('--' + boundary)
lines.append('Content-Disposition: form-data; name="message"')
lines.append('')
lines.append("hello")
lines.append('--' + boundary)
lines.append('Content-Disposition: form-data; name="uploadfile"; filename="uploadfile.txt"')
lines.append('Content-Type: text/plain')
lines.append('')
lines.append("hoge")
lines.append('')
lines.append("--" + boundary + "--")
lines.append('')
value = "\n".join(lines)
return value.encode(encoding)
def request_with_multipart_formdata():
req = urllib.request.Request(url)
req.add_header("Content-Type", "multipart/form-data; boundary=%s" % boundary)
data = multipart_formdata()
with urllib.request.urlopen(req, data) as response:
print(response.status)
request_with_multipart_formdata()
バイナリファイルを送信するサンプル
画像などのデータを送信する方法です
受信側が Content-Transfer-Encoding: base64
に対応していれば送信できるはずですが
import urllib
import urllib.request
import base64
url = "http://localhost:8080/upload"
encoding = "utf-8"
boundary = "--------python"
f = open("image.png", "rb", buffering=0)
file_data = f.read()
f.close()
def multipart_formdata():
value = '--' + boundary
value += 'Content-Disposition: form-data; name="message"'
value += ''
value += 'hello'
value += '--' + boundary
value += 'Content-Disposition: form-data; name="uploadfile"; filename="image.png"'
value += 'Content-Type: image/png'
value += 'Content-Transfer-Encoding: base64'
value += ''
value += str(base64.b64encode(file_data))
value += ''
value += "--" + boundary + "--"
value += ''
return value.encode(encoding)
def request_with_multipart_formdata():
req = urllib.request.Request(url)
req.add_header("Content-Type", "multipart/form-data; boundary=%s" % boundary)
data = multipart_formdata()
with urllib.request.urlopen(req, data) as response:
print(response.status)
request_with_multipart_formdata()
最後に
標準の urllib ではかなり辛いので素直に requests を使うのが良いと思います
0 件のコメント:
コメントを投稿