#python #python-2.7
#python #python-2.7
Вопрос:
У меня следующая проблема: мне нужно загрузить большие zip-файлы (обычно > 500 МБ, максимум около 5 ГБ) на веб-сайт, который затем обрабатывает эти файлы. Я делаю это в Python 2.7.16
32-разрядной версии Windows. К сожалению, я не могу изменить свою настройку (с 32-разрядной на 64-разрядную) и не могу установить дополнительные плагины Python (у меня есть запросы, urllib и urllib2 и несколько других установленных) из-за ограничений компании. Теперь мой код выглядит так:
import requests
FileList=["C:File01.zip", "C:FileA02.zip", "C:UserFile993.zip"]
UploadURL = "https://mywebsite.com/submitFile"
for FilePath in FileList:
print("Upload file: " str(FilePath))
session = requests.Session()
with open(FilePath, "rb") as file:
session.post(UploadURL,data={'file':'Send file'},files={'FileToBeUploaded':FilePath})
print("Upload done: " str(FilePath))
session.close()
Поскольку мой FileList
довольно длинный (> 100 записей), я просто вставил сюда его отрывок. Приведенный выше код хорошо работает, если размер файла меньше 600 МБ. Любой файл выше, который выдаст мне эту ошибку:
File "<stdin>", line 1, in <module>
File "C:UsersAAA253DesktopDingDong.py", line 39, in <module>
session.post(UploadURL,data={'file':'Send file'},files={'FileToBeUploaded':FilePath})
File "C:Python27libsite-packagesrequestssessions.py", line 522, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "C:Python27libsite-packagesrequestssessions.py", line 461, in request
prep = self.prepare_request(req)
File "C:Python27libsite-packagesrequestssessions.py", line 394, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "C:Python27libsite-packagesrequestsmodels.py", line 297, in prepare
self.prepare_body(data, files, json)
File "C:Python27libsite-packagesrequestsmodels.py", line 455, in prepare_body
(body, content_type) = self._encode_files(files, data)
File "C:Python27libsite-packagesrequestsmodels.py", line 158, in _encode_files
body, content_type = encode_multipart_formdata(new_fields)
File "C:Python27libsite-packagesrequestspackagesurllib3filepost.py", line 86, in encode_multipart_formdata
body.write(data)
MemoryError
Я уже проверил форум здесь, чтобы найти некоторые решения, но, к сожалению, я не смог найти ни одного подходящего решения. У кого-нибудь есть идея о том, как это сделать? Может ли это быть сделано путем загрузки файла по частям? Если да, то как загрузить файл по частям, чтобы сервер не «отменял» операцию?
Редактировать: используя ответ от @AKX, я использую этот код:
import requests
from requests_toolbelt.multipart import encoder
FileList=["C:File01.zip", "C:FileA02.zip", "C:UserFile993.zip"]
UploadURL = "https://mywebsite.com/submitFile"
for FilePath in FileList:
session = requests.Session()
with open(FilePath, 'rb') as f:
form = encoder.MultipartEncoder({"documents": (FilePath, f, "application/octet-stream"),"composite": "NONE",})
headers = {"Prefer": "respond-async", "Content-Type": form.content_type}
resp = session.post(UploadURL,data={'file':'Send file'},files={'FileToBeUploaded':form})
session.close()
Тем не менее я получаю почти те же ошибки:
File "<stdin>", line 1, in <module>
File "C:UsersAAA253DesktopDingDong.py", line 48, in <module>
resp = session.post(UploadURL,data={'file':'Send file'},files={'FileToBeUploaded':form})
File "C:Python27libsite-packagesrequests-2.24.0-py2.7.eggrequestssessions.py", line 578, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "C:Python27libsite-packagesrequests-2.24.0-py2.7.eggrequestssessions.py", line 516, in request
prep = self.prepare_request(req)
File "C:Python27libsite-packagesrequests-2.24.0-py2.7.eggrequestssessions.py", line 459, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "C:Python27libsite-packagesrequests-2.24.0-py2.7.eggrequestsmodels.py", line 317, in prepare
self.prepare_body(data, files, json)
File "C:Python27libsite-packagesrequests-2.24.0-py2.7.eggrequestsmodels.py", line 505, in prepare_body
(body, content_type) = self._encode_files(files, data)
File "C:Python27libsite-packagesrequests-2.24.0-py2.7.eggrequestsmodels.py", line 159, in _encode_files
fdata = fp.read()
File "buildbdist.win32eggrequests_toolbeltmultipartencoder.py", line 314, in read
File "buildbdist.win32eggrequests_toolbeltmultipartencoder.py", line 194, in _load
File "buildbdist.win32eggrequests_toolbeltmultipartencoder.py", line 256, in _write
File "buildbdist.win32eggrequests_toolbeltmultipartencoder.py", line 552, in append
MemoryError
Комментарии:
1. вы проверили, принимает ли ваш целевой сайт chunked?
Ответ №1:
Скорее всего, вам не понадобится requests-toolbelt
многопартенкодер потоковой передачи.
Даже если ограничения вашей компании запрещают установку новых пакетов, вы, скорее всего, можете добавить нужные вам части requests_toolbelt
(возможно, весь пакет) в каталог вашего проекта.
Комментарии:
1. Я реализовал это сейчас и расширил свой первый пост. Я все еще получаю ошибки.
2. Вам нужно использовать
data=form
, а неfiles={...: form}
.3. Хорошо, используя вашу идею, я все еще не добился этого. Я не вижу взаимодействия между кодом и моим веб-сайтом. На моем веб-сайте у меня есть 2 кнопки для отправки файла. Кнопка под названием «Отправить файл» запускает загрузку, в то время как на второй кнопке под названием «FileToBeUploaded» вам нужно выбрать файл, который вы хотите загрузить. Я делаю это совершенно неправильно, используя MultipartEncoder:
m = MultipartEncoder(fields={'file':'Send file', 'FileToBeUploaded': ('filename', open(FilePath, 'rb'), '.zip')}) r = session.post(UploadURL, data=m, headers={'Content-Type': m.content_type})
4. Но вы не получаете ошибку памяти с этой версией, верно? Затем нужно отправить правильные данные.
5. Ошибка памяти исчезла, но сервер не отвечает, поэтому я боюсь, что я не получаю сообщение об ошибке, но вместо этого отправка не активна (и поэтому также загрузка в память).