PythonはHTTPでのデータ転送を簡単にする多くのライブラリでサポートされています。
リクエスト`ライブラリは、Webスクレイピングでよく使われるため、最も人気のあるPythonパッケージの1つです。
また、サーバーとのやり取りにもよく使われています。
このライブラリは、JSONのような一般的なフォーマットでデータをアップロードすることを容易にしますが、同様にファイルをアップロードすることも容易にします。
このチュートリアルでは、Pythonの requests
ライブラリを使用してファイルをアップロードする方法について見ていきます。
この記事では、まず requests
ライブラリと post()
関数のシグネチャについて説明します。
次に、 requests
パッケージを使用して単一のファイルをアップロードする方法について説明します。
最後に、一回のリクエストで複数のファイルをアップロードする。
Python の Requests ライブラリで単一ファイルをアップロードする。
このチュートリアルでは、ファイルを送信する方法について説明し、ファイルの作成方法については触れません。
ここでは、my_file.txt
, my_file_2.txt
, my_file_3.txt
という3つのファイルを作成します。
最初に行うべきことは、ワークスペースに request
ライブラリをインストールすることです。
必須ではありませんが、ライブラリは仮想環境にインストールすることをお勧めします。
$ python3 -m venv .
グローバルなPythonのインストールに影響を与えないように、仮想環境をアクティブにします。
$ . bin/activate
では、pip
を使って requests
ライブラリをインストールしましょう。
$ pip install requests
新しいファイル single_uploader.py
を作成して、私たちのコードを保存します。
このファイルでは、まず requests
ライブラリをインポートしてください。
import requests
これで、ファイルをアップロードするための準備が整いました。
ファイルをアップロードする場合、ファイルを開いてコンテンツをストリーミングする必要があります。
結局のところ、アクセス権のないファイルをアップロードすることはできません。
これは open()
関数で行います。
open()`関数は、ファイルのパスとモードの2つのパラメータを受け取ります。
ファイルのパスは、絶対パスでも、スクリプトを実行している場所からの相対パスでもかまいません。
同じディレクトリにあるファイルをアップロードする場合は、ファイル名だけでかまいません。
第2引数のmodeは、rb
で表される「読み取りバイナリ」値を取ります。
この引数は、ファイルを読み込みモードで開き、バイナリ形式でファイルのデータを消費したいことをコンピュータに伝えます。
test_file = open("my_file.txt", "rb")
注意: ファイルをバイナリモードで読み込むことは重要である。
requestsライブラリは通常、
Content-Lengthヘッダを決定し、その値はバイト単位で指定します。
ファイルがバイトモードで読み込まれないと、ライブラリはContent-Length` に不正な値を取得し、ファイル送信時にエラーが発生する可能性があります。
このチュートリアルでは、無料の httpbin サービスにリクエストを行います。
この API を使うと、開発者は HTTP リクエストをテストすることができます。
ファイルを投稿するための URL を格納する変数を作成しましょう。
test_url = "http://httpbin.org/post"
これでリクエストを行うための準備が整いました。
ファイルをアップロードするために、 requests
ライブラリの post()
メソッドを使用します。
サーバーの URL と files
プロパティの 2 つの引数が必要です。
また、レスポンスを変数に保存するので、以下のコードを記述してください。
test_response = requests.post(test_url, files = {"form_field_name": test_file})
files` プロパティは辞書を受け取ります。
キーは、ファイルを受け入れるフォームフィールドの名前です。
値は、アップロードしたいファイルを開いたときのバイト数です。
通常、post()
メソッドが成功したかどうかを確認するために、レスポンスの HTTP ステータスコードをチェックします。
レスポンスオブジェクトである test_url
の ok
プロパティを利用することができます。
もしそれが真であれば、HTTPサーバーからのレスポンスを出力します。
この場合、リクエストの内容をechoします。
if test_response.ok:
print("Upload completed successfully!")
print(test_response.text)
else:
print("Something went wrong!")
では、実際に試してみましょう。
ターミナルで、python
コマンドを使用してスクリプトを実行します。
python single_uploader.py
出力はこのようになります。
Upload completed successfully!
{
"args": {},
"data": "",
"files": {
"form_field_name": "This is my file
I like my file
"
},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "189",
"Content-Type": "multipart/form-data; boundary=53bb41eb09d784cedc62d521121269f8",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.25.0",
"X-Amzn-Trace-Id": "Root=1-5fc3c190-5dea2c7633a02bcf5e654c2b"
},
"json": null,
"origin": "102.5.105.200",
"url": "http://httpbin.org/post"
}
サニティチェックとして、form_field_name
の値がファイルに書かれているものと一致していることを確認できます。
Python の requests ライブラリで複数のファイルをアップロードする。
リクエストを使って複数のファイルをアップロードするのは、単一のファイルとよく似ていますが、大きな違いはリストを使っていることです。
multi_uploader.py` というファイルを新規に作成し、以下のセットアップコードを記述します。
import requests
test_url = "http://httpbin.org/post"
変数 test_files
を作成し、複数のファイル名とファイル名を持つ辞書を作成します。
test_files = {
"test_file_1": open("my_file.txt", "rb"),
"test_file_2": open("my_file_2.txt", "rb"),
"test_file_3": open("my_file_3.txt", "rb")
}
前と同じように、キーはフォームフィールドの名前で、値はバイト単位のファイルです。
また、ファイル変数をタプルのリストとして作成することもできます。
それぞれのタプルは、ファイルを受け入れるフォーム・フィールドの名前と、その後に続くファイルの内容をバイト単位で含んでいます。
test_files = [("test_file_1", open("my_file.txt", "rb")),
("test_file_2", open("my_file_2.txt", "rb")),
("test_file_3", open("my_file_3.txt", "rb"))]
どちらでも構いませんので、好きなほうを選んでください。
ファイルのリストが準備できたら、前と同じようにリクエストを送信してその応答をチェックすることができます。
test_response = requests.post(test_url, files = test_files)
if test_response.ok:
print("Upload completed successfully!")
print(test_response.text)
else:
print("Something went wrong!")
このスクリプトを python
コマンドで実行します。
$ python multi_uploader.py
このような出力が表示されるでしょう。
Upload completed successfully!
{
"args": {},
"data": "",
"files": {
"test_file_1": "This is my file
I like my file
",
"test_file_2": "All your base are belong to us
",
"test_file_3": "It's-a me, Mario!
"
},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "470",
"Content-Type": "multipart/form-data; boundary=4111c551fb8c61fd14af07bd5df5bb76",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.25.0",
"X-Amzn-Trace-Id": "Root=1-5fc3c744-30404a8b186cf91c7d239034"
},
"json": null,
"origin": "102.5.105.200",
"url": "http://httpbin.org/post"
}
お疲れ様でした。
結論
この記事では、Pythonで requests
ライブラリを使用してファイルをアップロードする方法について学びました。
単一のファイルや複数のファイルをアップロードする場合、 post()
メソッドを少し調整するだけでよいのです。
また、アップロードが成功したことを確認するために、レスポンスの検証を行いました。