Wie sende ich eine multipart/form-data
mit Anfragen in Python? Wie man eine Datei sendet, verstehe ich, aber wie man die Formulardaten mit dieser Methode sendet, kann man nicht verstehen.
python
python-2.7
multipartform-data
python-requests
agrynchuk
quelle
quelle
files
Parameter verwendet werden, um beides zu tun, ist eine sehr schlechte API. Ich habe ein Problem mit dem Titel Senden mehrteiliger Daten angesprochen - wir benötigen eine bessere API , um dies zu beheben. Wenn Sie damit einverstanden sind, dass die Verwendung vonfiles
Parametern zum Senden von Daten mit mehreren Teilen bestenfalls irreführend ist, bitten Sie darum, die API in der obigen Ausgabe zu ändern.Antworten:
Wenn Sie einen
files
Parameter (ein Wörterbuch) angeben ,requests
wird grundsätzlich einmultipart/form-data
POST anstelle einesapplication/x-www-form-urlencoded
POST gesendet. Sie sind jedoch nicht darauf beschränkt, tatsächliche Dateien in diesem Wörterbuch zu verwenden:und httpbin.org informiert Sie darüber, mit welchen Headern Sie gepostet haben. in haben
response.json()
wir:Besser noch, Sie können den Dateinamen, den Inhaltstyp und zusätzliche Überschriften für jeden Teil weiter steuern, indem Sie ein Tupel anstelle einer einzelnen Zeichenfolge oder eines Byte-Objekts verwenden. Es wird erwartet, dass das Tupel zwischen 2 und 4 Elemente enthält. den Dateinamen, den Inhalt, optional einen Inhaltstyp und ein optionales Wörterbuch mit weiteren Kopfzeilen.
Ich würde das Tupelformular mit
None
als Dateinamen verwenden, damit derfilename="..."
Parameter aus der Anforderung für diese Teile entfernt wird:files
kann auch eine Liste von Tupeln mit zwei Werten sein, wenn Sie eine Bestellung und / oder mehrere Felder mit demselben Namen benötigen:Wenn Sie beide angeben ,
files
unddata
dann kommt es auf den Wert von ,data
was verwendet werden , um den POST - Körper zu schaffen. Wenndata
es sich um eine Zeichenfolge handelt, wird nur diese verwendet. Andernfalls werden beidedata
undfiles
verwendet, wobei die Elementedata
zuerst aufgeführt werden.Es gibt auch das hervorragende
requests-toolbelt
Projekt, das erweiterte Unterstützung für mehrere Teile umfasst . Es werden Felddefinitionen im gleichen Format wie derfiles
Parameter verwendet, im Gegensatzrequests
dazu wird standardmäßig kein Dateinamenparameter festgelegt. Darüber hinaus kann die Anforderung von geöffneten Dateiobjekten gestreamt werden, wobeirequests
zuerst der Anforderungshauptteil im Speicher erstellt wird:Felder folgen den gleichen Konventionen; Verwenden Sie ein Tupel mit 2 bis 4 Elementen, um einen Dateinamen, einen Teil-MIME-Typ oder zusätzliche Header hinzuzufügen. Im Gegensatz zum
files
Parameter wird kein Versuch unternommen, einen Standardwert zu findenfilename
, wenn Sie kein Tupel verwenden.quelle
multipart/form-data
Inhaltstyp den Grenzwert enthalten muss, der zur Abgrenzung der Teile im Post-Body verwendet wird. Wenn Sie denContent-Type
Header nicht setzen , wirdrequests
er auf den richtigen Wert gesetzt.multipart/form-data
ob der Wert vonfiles=
wahr ist. Wenn Sie also einemultipart/form-data
Anfrage senden müssen, aber keine Dateien enthalten, können Sie einen wahrheitsgemäßen, aber bedeutungslosen Wert wie{'':''}
unddata=
mit Ihrem Anfragetext festlegen . Wenn Sie dies tun, geben Sie denContent-Type
Header nicht selbst an.requests
wird es für Sie einstellen. Sie können die Wahrheitsüberprüfung hier sehen: github.com/psf/requests/blob/…files
Fügen Sie einfach alle Felder in das Diktat ein, es müssen keine Dateien sein (verwenden Sie einfach das Tupelformular und setzen Sie den Dateinamen aufNone
). Besser noch, nutzen Sie dasrequests_toolbelt
Projekt.Seit die vorherigen Antworten geschrieben wurden, haben sich die Anfragen geändert. Schauen Sie sich den Bug-Thread bei Github an, um mehr Details zu erfahren, und diesen Kommentar als Beispiel.
Kurz gesagt, der Parameter files nimmt a an,
dict
wobei der Schlüssel der Name des Formularfelds und der Wert entweder eine Zeichenfolge oder ein Tupel mit 2, 3 oder 4 Längen ist, wie im Abschnitt POST a Multipart-Encoded File in den Anforderungen beschrieben Schnellstart:Oben ist das Tupel wie folgt zusammengesetzt:
Wenn der Wert nur eine Zeichenfolge ist, entspricht der Dateiname dem Schlüssel wie im Folgenden:
Wenn der Wert ein Tupel ist und der erste Eintrag
None
der Dateiname ist, wird er nicht berücksichtigt:quelle
name
und unterscheiden müssen,filename
aber auch mehrere Felder mit demselben Namen haben?files
Tupels zu übergeben, funktioniert nicht mehr: Sie müssenrequests.post
data
stattdessen Parameter verwenden, um zusätzliche Nicht-Datei-multipart/form-data
Parameter zu sendenNone
anstelle einer leeren Zeichenfolge scheint zu funktionierenSie müssen den
files
Parameter verwenden, um eine mehrteilige POST-Anfrage zu senden, auch wenn Sie keine Dateien hochladen müssen.Aus der ursprünglichen Anforderungsquelle :
Der relevante Teil ist:
file-tuple can be a
2-tuple
, .3-tuple
or a
4-tuple
Basierend auf dem oben Gesagten sieht die einfachste mehrteilige Formularanforderung, die sowohl hochzuladende Dateien als auch Formularfelder enthält, folgendermaßen aus:
☝ Beachten Sie das
None
als erstes Argument im Tupel für Nur-Text-Felder - dies ist ein Platzhalter für das Dateinamenfeld, das nur für Datei-Uploads verwendet wird, aber für Textfelder, dieNone
als erster Parameter übergeben werden, ist erforderlich, damit die Daten gesendet werden .Mehrere Felder mit demselben Namen
Wenn Sie mehrere Felder mit demselben Namen veröffentlichen müssen, können Sie anstelle eines Wörterbuchs Ihre Nutzdaten als Liste (oder Tupel) von Tupeln definieren:
API für Streaming-Anforderungen
Wenn die oben genannte API für Sie nicht pythonisch genug ist, sollten Sie das Anforderungs-Toolbelt (
pip install requests_toolbelt
) verwenden, eine Erweiterung des Kernanforderungsmoduls, das das Streaming von Datei-Uploads unterstützt, sowie den MultipartEncoder , der anstelle von verwendet werdenfiles
kann und der dies auch ermöglicht Sie definieren die Nutzdaten als Wörterbuch, Tupel oder Liste.MultipartEncoder
kann sowohl für mehrteilige Anfragen mit als auch ohne tatsächliche Upload-Felder verwendet werden. Es muss demdata
Parameter zugewiesen werden.Wenn Sie mehrere Felder mit demselben Namen senden müssen oder wenn die Reihenfolge der Formularfelder wichtig ist, kann anstelle eines Wörterbuchs ein Tupel oder eine Liste verwendet werden:
quelle
file.py
im selben Ordner wie Ihr Skript befindet.None
anstelle einer leeren Zeichenfolge verwenden. Dann enthalten Anfragen überhaupt keinen Dateinamen. Also stattdessenContent-Disposition: form-data; name="action"; filename=""
wird es seinContent-Disposition: form-data; name="action"
. Dies war für mich entscheidend, damit der Server diese Felder als Formularfelder und nicht als Dateien akzeptiert.Hier ist das einfache Code-Snippet zum Hochladen einer einzelnen Datei mit zusätzlichen Parametern mithilfe von Anforderungen:
Bitte beachten Sie, dass Sie keinen Inhaltstyp explizit angeben müssen.
HINWEIS: Wollte eine der oben genannten Antworten kommentieren, konnte dies jedoch aufgrund der geringen Reputation nicht. Daher wurde hier eine neue Antwort verfasst.
quelle
Sie müssen das
name
Attribut der Upload-Datei verwenden, das sich im HTML-Code der Site befindet. Beispiel:Siehst du
name="image">
? Sie finden es im HTML-Code einer Site zum Hochladen der Datei. Sie müssen es verwenden, um die Datei mit hochzuladenMultipart/form-data
Skript:
Fügen Sie hier anstelle des Bildes den Namen der Upload-Datei in HTML hinzu
Wenn für den Upload die Schaltfläche zum Hochladen erforderlich ist, können Sie Folgendes verwenden:
Starten Sie dann die Anfrage
Und fertig, Datei erfolgreich hochgeladen
quelle
Senden Sie einen mehrteiligen / Formulardatenschlüssel und -wert
Curl-Befehl:
Python- Anfragen - Kompliziertere POST-Anfragen :
Senden Sie eine mehrteilige / Formulardatendatei
Curl-Befehl:
Python- Anforderungen - POST eine Multipart-codierte Datei :
das ist alles.
quelle
Hier ist das Python-Snippet, das Sie benötigen, um eine große einzelne Datei als mehrteilige Formulardaten hochzuladen. Mit NodeJs Multer-Middleware, die auf der Serverseite ausgeführt wird.
Für die Serverseite überprüfen Sie bitte die Multer-Dokumentation unter: https://github.com/expressjs/multer. Hier wird das Feld single ('fieldName') verwendet, um eine einzelne Datei zu akzeptieren, wie in:
quelle