web-dev-qa-db-ja.com

pythonリクエストモジュールを使用して、1つのリクエストで複数のファイルをアップロードする

Python requests module は、単一のリクエストで単一のファイルをアップロードする方法に関する優れたドキュメントを提供します:

 files = {'file': open('report.xls', 'rb')}

複数のファイルをアップロードしようとしてこのコードを使用して、その例を拡張してみました。

 files = {'file': [open('report.xls', 'rb'), open('report2.xls, 'rb')]}

しかし、それはこのエラーをもたらしました:

 File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py",      line 1052, in splittype
 match = _typeprog.match(url)
 TypeError: expected string or buffer

このモジュールを使用して、単一のリクエストでファイルのリストをアップロードすることは可能ですか?

23
user462455

1つのリクエストで同じキー値を持つファイルのリストをアップロードするには、各タプルの最初のアイテムをキー値として、ファイルオブジェクトを2番目として、タプルのリストを作成できます。

files = [('file', open('report.xls', 'rb')), ('file', open('report2.xls', 'rb'))]
30
Ryan Fau

複数の辞書エントリを追加することで、異なるキー値を持つ複数のファイルをアップロードできます。

files = {'file1': open('report.xls', 'rb'), 'file2': open('otherthing.txt', 'rb')}
r = requests.post('http://httpbin.org/post', files=files)
17
Lukasa

documentation には明確な答えが含まれています。

引用:

1回のリクエストで複数のファイルを送信できます。たとえば、複数のファイルフィールド「images」を含むHTMLフォームに画像ファイルをアップロードするとします。

これを行うには、ファイルに(form_field_name、file_info)のタプルのリストを設定します。

url = 'http://httpbin.org/post'
multiple_files = [('images', ('foo.png', open('foo.png', 'rb'), 'image/png')),
                      ('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))]
r = requests.post(url, files=multiple_files)
r.text

# {
#  ...
#  'files': {'images': 'data:image/png;base64,iVBORw ....'}
#  'Content-Type': 'multipart/form-data; boundary=3131623adb2043caaeb5538cc7aa0b3a',
#  ...
# }
13
Wade Anderson

私は少し混乱していますが、リクエストでファイルを直接開くこと(ただし、公式のリクエストガイドに同じことが書かれています)はそれほど安全ではありません。

ちょうど試して:

import os
import requests
file_path = "/home/user_folder/somefile.txt"
files = {'somefile': open(file_path, 'rb')}
r = requests.post('http://httpbin.org/post', files=files)

はい、すべて大丈夫ですが、

os.rename(file_path, file_path)

そしてあなたは得るでしょう:

PermissionError:The process cannot access the file because it is being used by another process

正しくない場合は修正してください。ファイルがまだ開かれているようで、ファイルを閉じる方法がわかりません。

これの代わりに私は使います:

import os
import requests
#let it be folder with files to upload
folder = "/home/user_folder/"
#dict for files
upload_list = []
for files in os.listdir(folder):
    with open("{folder}{name}".format(folder=folder, name=files), "rb") as data:
        upload_list.append(files, data.read())
r = request.post("https://httpbin.org/post", files=upload_list)
#trying to rename uploaded files now
for files in os.listdir(folder):
    os.rename("{folder}{name}".format(folder=folder, name=files), "{folder}{name}".format(folder=folder, name=files))

エラーは発生しなくなったので、この方法を使用して複数のファイルをアップロードすることをお勧めします。そうしないと、エラーが発生する可能性があります。この答えが誰かを助け、貴重な時間を節約することを願っています。

1
Mike Mint

複数の画像をアップロードするには、ファイルリストを作成する必要があります。

file_list = [  
       ('Key_here', ('file_name1.jpg', open('file_path1.jpg', 'rb'), 'image/png')),
       ('key_here', ('file_name2.jpg', open('file_path2.jpg', 'rb'), 'image/png'))
   ]

r = requests.post(url, files=file_list)

同じキーでファイルを送信する場合は、各要素のキーを同じに保ち、別のキーの場合はキーを変更するだけです。

ソース: https://stackabuse.com/the-python-requests-module/

0
Abdul Haseeb

pythonリストに複数のファイルがある場合、eval()を内包表記で使用して、requests post filesパラメータのファイルをループできます。

file_list = ['001.jpg', '002.jpg', '003.jpg']
files=[eval(f'("inline", open("{file}", "rb"))') for file in file_list ]

requests.post(
        url=url,
        files=files
)
0
joshhu