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
是否可以使用此模块在单个请求中上传文件列表,以及如何?
答案 0 :(得分:21)
要在单个请求中上传具有相同键值的文件列表,您可以创建元组列表,每个元组中的第一项作为键值,文件对象作为第二项:
files = [('file', open('report.xls', 'rb')), ('file', open('report2.xls', 'rb'))]
答案 1 :(得分:13)
可以通过添加多个字典条目来上载具有不同键值的多个文件:
files = {'file1': open('report.xls', 'rb'), 'file2': open('otherthing.txt', 'rb')}
r = requests.post('http://httpbin.org/post', files=files)
答案 2 :(得分:10)
documentation包含明确的答案。
引用:
您可以在一个请求中发送多个文件。例如,假设你 想要将图像文件上传到具有多个文件字段的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',
# ...
# }
答案 3 :(得分:0)
您需要创建文件列表以上传多张图像:
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)
如果要使用同一密钥发送文件,则需要使每个元素的密钥保持相同,而对于不同的密钥,只需更改密钥即可。
答案 4 :(得分:0)
我有点困惑,但是直接在请求中打开文件(无论如何在官方请求指南中写明)都不是那么“安全”。
只需尝试:
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))
现在我们没有收到错误,所以我建议使用这种方式上传多个文件,否则您可能会收到一些错误。 希望此答案对您有所帮助并节省无价的时间。
答案 5 :(得分:0)
如果python列表中有多个文件,则可以理解地使用<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/appTourViewPager"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_above="@+id/appTourIndicator"
app:layout_constraintBottom_toTopOf="@+id/appTourIndicator"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<me.relex.circleindicator.CircleIndicator3
android:id="@+id/appTourIndicator"
android:layout_width="match_parent"
android:layout_height="45dp"
app:ci_drawable="@drawable/circle_radius_selected"
app:ci_drawable_unselected="@drawable/circle_radius_unselected"
app:ci_height="6dp"
app:ci_margin="5dp"
app:ci_width="6dp"
app:layout_constraintBottom_toBottomOf="@id/appTourViewPager"
app:layout_constraintBottom_toTopOf="@+id/btnSignIn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btnSignIn"
style="?android:borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:maxLines="3"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceMedium"
app:layout_constraintBottom_toTopOf="@+id/btnGetStartedNow"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btnGetStartedNow"
style="@style/Button.Blue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:text="@string/getStartedNow"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
遍历requests post files参数中的文件。
eval()
答案 6 :(得分:0)
在我的情况下,上传文件夹内的所有图像只是添加带有索引的键
例如键=“图片”,例如循环中的“ images [0]”
photosDir = 'allImages'
def getFilesList(self):
listOfDir = os.listdir(os.path.join(os.getcwd()+photosDir))
setOfImg = []
for key,row in enumerate(listOfDir):
print(os.getcwd()+photosDir+str(row) , 'Image Path')
setOfImg.append((
'images['+str(key)+']',(row,open(os.path.join(os.getcwd()+photosDir+'/'+str(row)),'rb'),'image/jpg')
))
print(setOfImg)
return setOfImg
答案 7 :(得分:0)
如果您有表单中的文件并希望将其转发到其他 URL 或 API。这是一个将多个文件和其他表单数据转发到其他 URL 的示例。
images = request.files.getlist('images')
files = []
for image in images:
files.append(("images", (image.filename, image.read(), image.content_type)))
r = requests.post(url="http://example.com/post", data={"formdata1": "strvalue", "formdata2": "strvalue2"}, files=files)