Jak wysłać multipart/form-data
zapytanie w pythonie? Jak wysłać plik, rozumiem, ale jak wysłać dane formularza tą metodą, nie mogę zrozumieć.
python
python-2.7
multipartform-data
python-requests
agrynchuk
źródło
źródło
files
parametr jest używany do obu tych zadań, jest bardzo złym API. Podniosłem problem zatytułowany Wysyłanie danych wieloczęściowych - potrzebujemy lepszego interfejsu API, aby to naprawić. Jeśli zgadzasz się, że użyciefiles
parametru do wysyłania danych wielopartyjnych jest co najmniej mylące, poproś o zmianę interfejsu API w powyższym problemie.Odpowiedzi:
Zasadniczo, jeśli podasz
files
parametr (słownik), wówczasrequests
wyślemultipart/form-data
test POST zamiastapplication/x-www-form-urlencoded
POST. Nie jesteś ograniczony do używania rzeczywistych plików w tym słowniku, jednak:i httpbin.org informuje, z jakimi nagłówkami napisałeś; w
response.json()
mamy:Co więcej, możesz dalej kontrolować nazwę pliku, typ zawartości i dodatkowe nagłówki dla każdej części za pomocą krotki zamiast pojedynczego ciągu znaków lub obiektu bajtów. Krotka powinna zawierać od 2 do 4 elementów; nazwa pliku, treść, opcjonalnie typ zawartości i opcjonalny słownik dalszych nagłówków.
Użyłbym formularza krotkowego z
None
nazwą pliku, abyfilename="..."
parametr został usunięty z żądania dla tych części:files
może być również listą krotek o dwóch wartościach, jeśli potrzebujesz zamówienia i / lub wielu pól o tej samej nazwie:Jeśli podasz zarówno
files
adata
, to zależy od wartości zdata
co zostanie użyte do utworzenia treści testu POST. Jeślidata
jest łańcuchem, zostanie użyty tylko ten ciąg; w przeciwnym razie obadata
ifiles
są używane, z elementamidata
wymienionymi na początku.Istnieje również doskonały
requests-toolbelt
projekt, który obejmuje zaawansowane wsparcie Multipart . Przyjmuje definicje pól w tym samym formacie cofiles
parametr, ale w przeciwieństwie dorequests
do domyślnie nie ustawia parametru nazwy pliku. Ponadto może przesyłać strumieniowo żądanie z otwartych obiektów plikowych, gdzierequests
najpierw skonstruuje treść żądania w pamięci:Pola są zgodne z tymi samymi konwencjami; użyj krotki zawierającej od 2 do 4 elementów, aby dodać nazwę pliku, część typu MIME lub dodatkowe nagłówki. W przeciwieństwie do
files
parametru, niefilename
podejmuje się próby znalezienia wartości domyślnej, jeśli nie zostanie użyta krotka.źródło
multipart/form-data
Content-Type musi zawierać wartość graniczną używaną do deliniowania części w treści postu. Brak ustawieniaContent-Type
nagłówka gwarantuje, żerequests
ustawi on prawidłową wartość.multipart/form-data
jakby wartośćfiles=
true była prawdziwa, więc jeśli chcesz wysłaćmultipart/form-data
żądanie, ale nie zawierasz żadnych plików, możesz ustawić prawdziwą, ale bez znaczenia wartość, taką jak{'':''}
i ustawićdata=
w treści żądania. Jeśli to robisz, nie udostępniajContent-Type
nagłówka samodzielnie;requests
ustawię to dla ciebie. Prawdę możesz sprawdzić tutaj: github.com/psf/requests/blob/…files
dykta, nie muszą to być pliki (po prostu użyj formularza krotki i ustaw nazwę pliku naNone
). Jeszcze lepiej, skorzystaj zrequests_toolbelt
projektu.Od czasu napisania poprzednich odpowiedzi żądania uległy zmianie. Zajrzyj do wątku błędów w Github, aby uzyskać więcej szczegółów i ten komentarz na przykład.
Krótko mówiąc, parametr files przyjmuje a
dict
z kluczem będącym nazwą pola formularza, a wartością jest albo ciąg znaków, albo krotka o długości 2, 3 lub 4, jak opisano w sekcji POST pliku wieloczęściowego w żądaniach szybki start:W powyższym krotka składa się w następujący sposób:
Jeśli wartość jest tylko ciągiem, nazwa pliku będzie taka sama jak klucz, jak poniżej:
Jeśli wartością jest krotka, a pierwszym wpisem jest
None
nazwa pliku, właściwość nie zostanie uwzględniona:źródło
name
ifilename
ale także wiele pól o tej samej nazwie?files
krotki już nie działa: trzeba użyćrequests.post
data
parametru zamiast wysłać źródło dodatkowego zakaz plikówmultipart/form-data
parametrówNone
zamiast pustego ciągu wydaje się działaćMusisz użyć tego
files
parametru, aby wysłać wieloczęściowe żądanie POST, nawet jeśli nie musisz przesyłać żadnych plików.Z oryginalnego źródła żądań :
Odpowiednia część to:
file-tuple can be a
2-tuple
, .3-tuple
or a
4-tuple
Na podstawie powyższego najprostsze wieloczęściowe żądanie formularza, które zawiera zarówno pliki do przesłania, jak i pola formularza, będzie wyglądać następująco:
☝ Zauważ
None
jako pierwszy argument w krotce dla pól zwykłego tekstu - jest to symbol zastępczy pola nazwy pliku, który jest używany tylko do przesyłania plików, ale dla pól tekstowych przekazywanych,None
ponieważ pierwszy parametr jest wymagany do przesłania danych .Wiele pól o tej samej nazwie
Jeśli musisz opublikować wiele pól o tej samej nazwie, zamiast słownika możesz zdefiniować ładunek jako listę (lub krotkę) krotek:
Interfejs API żądań przesyłania strumieniowego
Jeśli powyższy interfejs API nie jest dla Ciebie wystarczający w Pythonie, zastanów się nad użyciem żądania toolbelt (
pip install requests_toolbelt
), który jest rozszerzeniem podstawowego modułu żądań , który zapewnia obsługę przesyłania strumieniowego plików, a także MultipartEncoder, którego można użyć zamiast niegofiles
i który pozwala definiujesz ładunek jako słownik, krotkę lub listę.MultipartEncoder
może być używany zarówno do żądań wieloczęściowych z lub bez rzeczywistych pól przesyłania. Musi być przypisany dodata
parametru.Jeśli musisz wysłać wiele pól o tej samej nazwie lub jeśli kolejność pól formularza jest ważna, zamiast słownika można użyć krotki lub listy:
źródło
file.py
znajduje się w tym samym folderze co skrypt.None
zamiast pustego ciągu. Wówczas żądania w ogóle nie będą zawierać nazwy pliku. Więc zamiastContent-Disposition: form-data; name="action"; filename=""
tego będzieContent-Disposition: form-data; name="action"
. Było to dla mnie krytyczne, aby serwer zaakceptował te pola jako pola formularza, a nie jako pliki.Oto prosty fragment kodu umożliwiający przesłanie pojedynczego pliku z dodatkowymi parametrami za pomocą żądań:
Pamiętaj, że nie musisz jawnie określać żadnego rodzaju treści.
UWAGA: Chciałem skomentować jedną z powyższych odpowiedzi, ale nie mógł z powodu niskiej reputacji, dlatego opracowałem tutaj nową odpowiedź.
źródło
Musisz użyć
name
atrybutu pliku do przesłania, który znajduje się w kodzie HTML witryny. Przykład:Widzisz
name="image">
? Możesz go znaleźć w kodzie HTML strony do przesłania pliku. Musisz go użyć do przesłania plikuMultipart/form-data
scenariusz:
W miejscu obrazu dodaj nazwę pliku do przesłania w formacie HTML
Jeśli przesyłanie wymaga kliknięcia przycisku przesyłania, możesz użyć w ten sposób:
Następnie uruchom żądanie
I gotowe, plik przesłany pomyślnie
źródło
Wyślij klucz i wartość danych wieloczęściowych / formularzy
polecenie zwijania:
zapytania python - bardziej skomplikowane żądania POST :
Wyślij plik danych wieloczęściowych / formularzy
polecenie zwijania:
zapytania w języku Python - POST pliku wieloczęściowego :
to wszystko.
źródło
Oto fragment kodu w pythonie, który musisz przesłać jeden duży pojedynczy plik jako dane wieloczęściowe. Z oprogramowaniem pośrednim NodeJs Multer działającym po stronie serwera.
Po stronie serwera sprawdź dokumentację multera pod adresem : https://github.com/expressjs/multer tutaj pojedynczy pole („fieldName”) służy do akceptacji jednego pliku, jak w:
źródło