Le Python module de requêtes fournit une bonne documentation sur la façon de télécharger un seul fichier dans une seule requête:
files = {'file': open('report.xls', 'rb')}
J'ai essayé d'étendre cet exemple en utilisant ce code dans une tentative de téléchargement de plusieurs fichiers:
files = {'file': [open('report.xls', 'rb'), open('report2.xls, 'rb')]}
mais cela a entraîné cette erreur:
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
Est-il possible de télécharger une liste de fichiers en une seule requête en utilisant ce module, et comment?
Pour télécharger une liste de fichiers avec la même valeur de clé dans une seule demande, vous pouvez créer une liste de tuples avec le premier élément de chaque tuple comme valeur de clé et l'objet fichier comme deuxième:
files = [('file', open('report.xls', 'rb')), ('file', open('report2.xls', 'rb'))]
Plusieurs fichiers avec différentes valeurs de clé peuvent être téléchargés en ajoutant plusieurs entrées de dictionnaire:
files = {'file1': open('report.xls', 'rb'), 'file2': open('otherthing.txt', 'rb')}
r = requests.post('http://httpbin.org/post', files=files)
Le documentation contient une réponse claire.
Cité:
Vous pouvez envoyer plusieurs fichiers en une seule demande. Par exemple, supposons que vous souhaitiez télécharger des fichiers image dans un formulaire HTML avec un champ de fichiers multiples "images":
Pour ce faire, définissez simplement les fichiers sur une liste de tuples de (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',
# ...
# }
Je suis un peu confus, mais ouvrir directement le fichier dans la demande (même si cela est écrit dans le guide des demandes officielles) n'est pas si "sûr".
Essayez simplement:
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)
Oui, tout ira bien, mais:
os.rename(file_path, file_path)
Et vous obtiendrez:
PermissionError:The process cannot access the file because it is being used by another process
Veuillez me corriger si je ne me trompe pas, mais il semble que le fichier soit toujours ouvert et je ne connais aucun moyen de le fermer.
Au lieu de cela, j'utilise:
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))
Maintenant, nous n'obtenons pas d'erreurs, donc je recommande d'utiliser cette façon de télécharger plusieurs fichiers ou vous pourriez recevoir des erreurs. J'espère que cette réponse aidera bien quelqu'un et économisera un temps inestimable.
Vous devez créer une liste de fichiers pour télécharger plusieurs images:
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)
Si vous souhaitez envoyer des fichiers sur la même clé, vous devez conserver la même clé pour chaque élément, et pour une clé différente, changez simplement les clés.
Si vous avez plusieurs fichiers dans une liste python, vous pouvez utiliser eval()
dans une compréhension pour parcourir les fichiers dans le paramètre des requêtes 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
)