Wie senden Sie eine multipart/form-data
mit Anfragen in Python? Wie man eine Datei sendet, verstehe ich, aber wie man die Formulardaten mit dieser Methode senden kann nicht verstehen.Wie senden Sie ein "multipart/form-data" mit Anfragen in Python?
Antwort
Grundsätzlich, wenn Sie einen files
Parameter (ein Wörterbuch) angeben, dann einen multipart/form-data
POST anstelle eines application/x-www-form-urlencoded
POST senden requests
wird. Sie sind nicht zu dem tatsächlichen Dateien in diesem Wörterbuch beschränkt, jedoch:
>>> import requests
>>> response = requests.post('http://httpbin.org/post', files=dict(foo='bar'))
>>> response.status_code
200
und httpbin.org lassen Sie wissen, was Header, die Sie mit gebucht; in response.json()
haben wir:
>>> from pprint import pprint
>>> pprint(response.json()['headers'])
{u'Accept': u'*/*',
u'Accept-Encoding': u'gzip, deflate, compress',
u'Connection': u'close',
u'Content-Length': u'141',
u'Content-Type': u'multipart/form-data; boundary=33b4531a79be4b278de5f5688fab7701',
u'Host': u'httpbin.org',
u'User-Agent': u'python-requests/2.2.1 CPython/2.7.6 Darwin/13.2.0',
u'X-Request-Id': u'eaf6baf8-fc3d-456b-b17d-e8219ccef1b1'}
files
auch eine Liste von zwei Wertetupeln sein kann, wenn Sie Bestellung und/oder mehrere Felder mit demselben Namen:
requests.post('http://requestb.in/xucj9exu', files=(('foo', 'bar'), ('spam', 'eggs')))
Wenn Sie sowohl files
angeben und data
, dann hängt es von dem Wert von data
ab, was verwendet wird, um den POST-Körper zu erstellen. Wenn data
eine Zeichenfolge ist, wird sie nur verwendet; andernfalls werden sowohl data
als auch files
verwendet, wobei die Elemente in data
zuerst aufgeführt werden.
Dies wird jedes Ding kodieren, das als Dateiparameter in der Multipart-Kodierung an 'files' gesendet wird. Dies erzeugt kein strenges Formular, sondern ein Formular mit allen Dateiparametern. Siehe [this] (https://github.com/kennethreitz/requests/issues/1081) als Referenz. –
@ sigmavirus24: Die Anfrage-API hat sich weiterentwickelt, seit ich das gepostet habe; Lassen Sie mich untersuchen, ob dies jetzt ein Update benötigt. In jedem Fall muss diese Ecke der API [seit einiger Zeit überarbeitet werden] (https://github.com/kennethreitz/requests/issues/935). –
entschuldigt. StackOverflow bringt das an die Spitze und ich vergesse die Reorganisationsfragen und ich muss mir die beantworteten/gefragten Daten anschauen. –
Da die vorherigen Antworten geschrieben wurden, haben sich die Anforderungen geändert. Werfen Sie einen Blick auf die bug thread at Github für weitere Details und this comment für ein Beispiel.
Kurz gesagt, der Parameter files nimmt eine dict
mit dem Schlüssel der Name des Formularfelds und der Wert ist entweder eine Zeichenfolge oder ein 2, 3 oder 4-Länge Tupel, wie im Abschnitt POST a Multipart-Encoded File in den Anfragen beschrieben Schnellstart:
>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
in dem obigen wird das Tupel wie folgt zusammen:
(filename, data, content_type, headers)
Wenn der Wert nur eine Zeichenfolge ist, wird der Dateiname der gleiche wie der Schlüssel sein, wie in der folgenden:
>>> files = {'obvius_session_id': '72c2b6f406cdabd578c5fd7598557c52'}
Content-Disposition: form-data; name="obvius_session_id"; filename="obvius_session_id"
Content-Type: application/octet-stream
72c2b6f406cdabd578c5fd7598557c52
Wenn der Wert ein Tupel und der erste Eintrag None
die Dateiname-Eigenschaft nicht enthalten sein:
>>> files = {'obvius_session_id': (None, '72c2b6f406cdabd578c5fd7598557c52')}
Content-Disposition: form-data; name="obvius_session_id"
Content-Type: application/octet-stream
72c2b6f406cdabd578c5fd7598557c52
Was ist, wenn Sie den Namen und den Dateinamen unterscheiden müssen, aber mehrere Felder mit demselben Namen haben? – Michael
Ich habe ein ähnliches Problem wie @Michael. Kannst du dir die Frage ansehen und etwas vorschlagen? [link] (http://stackoverflow.com/questions/30683352/how-to-upload-multipart-encode-file-and-form-data-as-a-payload) – Shaardool
hat jemand dieses Problem mit mehreren Feldern gelöst mit dem gleichen Namen? – user3131037
Sie müssen die files
Parameter verwenden, um eine mehrteilige Form POST-Anfrage zu senden, auch wenn Sie Sie müssen keine Dateien hochladen.
Von der ursprünglichen requests Quelle:
def request(method, url, **kwargs):
"""Constructs and sends a :class:`Request <Request>`.
...
:param files: (optional) Dictionary of ``'name': file-like-objects``
(or ``{'name': file-tuple}``) for multipart encoding upload.
``file-tuple`` can be a 2-tuple ``('filename', fileobj)``,
3-tuple ``('filename', fileobj, 'content_type')``
or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``,
where ``'content-type'`` is a string
defining the content type of the given file
and ``custom_headers`` a dict-like object
containing additional headers to add for the file.
Die einfachste mehrteiliger Form Anforderung, die beiden Dateien Felder zum Hochladen und Form enthält werden wie folgt aussehen:
multipart_form_data = {
'file1': open('myfile.zip', 'rb'),
'file2': ('custom_file_name.zip', open('myfile.zip', 'rb')),
'action': ('', 'store'),
'path': ('', '/path1')
}
response = requests.post('https://httpbin.org/post', files=multipart_form_data)
print(response.content)
☝ Beachten Sie die leere Zeichenfolge als das erste Element im Tupel für Nur-Text-Felder - dies ist ein Platzhalter für das Feld Dateiname, das nur für Datei-Uploads verwendet wird, aber für das Textfeld muss der leere Platzhalter in der Reihenfolge vorhanden sein für die Daten eingereicht werden.
Wenn diese API nicht pythonic genug für Sie ist, oder wenn Sie mehrere Felder, die mit dem gleichen Namen schreiben müssen, sollten Sie dann mit requests toolbelt (
pip install requests_toolbelt
), die eine Erweiterung des
core requests Modul ist die Unterstützung für die Datei zur Verfügung stellt Upload-Streaming sowie die
MultipartEncoder, die anstelle von
files
verwendet werden kann, und die Parameter sowohl als Wörterbücher und Tupel akzeptiert.
MultipartEncoder
kann sowohl für mehrteilige Anfragen mit oder ohne tatsächliche Upload-Felder verwendet werden. Sie muss dem Parameter data
zugewiesen werden.
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
multipart_data = MultipartEncoder(
fields={
# a file upload field
'file': ('file.py', open('file.py', 'rb'), 'text/plain')
# plain text fields
'field0': 'value0',
'field1': 'value1',
}
)
response = requests.post('http://httpbin.org/post', data=multipart_data,
headers={'Content-Type': multipart_data.content_type})
Wenn Sie mehrere Felder mit demselben Namen zu schicken, oder wenn Auftrag von Formularfeldern wichtig ist, dann ein Tupel oder eine Liste kann anstelle eines Wörterbuchs verwendet werden, das heißt:
multipart_data = MultipartEncoder(
fields=(
('action', 'store'),
('path', '/path1'),
('path', '/path2'),
('path', '/path3'),
)
)
Vielen Dank dafür. Die Reihenfolge der Schlüssel war mir wichtig und das half sehr. – Splendor
Erstaunlich. Unerklärlicherweise benötigt eine API, mit der ich arbeite, zwei verschiedene Werte für denselben Schlüssel. Das ist großartig. Vielen Dank. – ajon
@ccpizza, was eigentlich diese Zeile bedeutet? > "('file.py', öffnen ('file.py', 'rb'), 'text/plain')". Es funktioniert nicht für mich :( –
- 1. Wie senden Sie ein "multipart/related" mit Anfragen in Python?
- 2. So senden Sie zwei Anfragen zur gleichen Zeit mit Python
- 3. Senden eines Formulars mit Anfragen Python
- 4. MultipartFormData Spec
- 5. senden Sie Anfragen mit verschiedenen HTTP-Methoden
- 6. Python: Senden Sie mehrere POST-Anfragen auf der gleichen Seite
- 7. Erhalten Sie HTML mit Python-Anfragen?
- 8. Python-Anfragen frieren manchmal ein
- 9. Play 2.0 So veröffentlichen Sie MultipartFormData mit WS.url oder WS.WSRequest
- 10. So verwenden Sie Cookies in Python-Anfragen
- 11. Python-Anfragen: JSON und Datei in einer einzigen Anfrage senden
- 12. Python-Anfragen mit Multithreading
- 13. Params in Anfragen (Python)
- 14. Senden von HTTP-Anfragen
- 15. Hochladen von Dateien mit Anfragen und senden Sie zusätzliche Daten
- 16. So senden Sie synchrone Anfragen mit $ http von Angular.js
- 17. Simultane NSURLConnection-Anfragen senden
- 18. Wie ein Cookie zum Cookiejar in Python Anfragen Bibliothek hinzufügen
- 19. MultipartFormData in Play 2.0 testen FakeRequest
- 20. Senden mehrerer SOAP-Anfragen in einem Paket
- 21. Wie Mail mit Python senden
- 22. Verwenden von Python 'Anfragen' zu senden JSON boolean
- 23. Kann Applescript Anfragen senden oder senden?
- 24. python-Anfragen Post mit Unicode-Dateinamen
- 25. Wie erhalten Python-Anfragen ein selbstsigniertes SSL-Zertifikat?
- 26. Python XMLRPC mit gleichzeitigen Anfragen
- 27. Parallel API-Anfragen in Python
- 28. Python Anfragen Anruf mit URL mit Parametern
- 29. HTTP-Anfragen (Python + VBA)
- 30. Wie wird eine weitere Anfrage gesendet, wenn sie einmal mit Python-Anfragen fehlgeschlagen ist?
Ihre Frage ist nicht wirklich klar. Was willst du erreichen? Möchten Sie "multipart/form-data" ohne Datei-Upload im Formular senden? –
Die Tatsache, dass 'files' Parameter verwendet wird, um beides zu tun, ist eine sehr schlechte API. Ich habe das Problem mit dem Titel [Senden von mehrteiligen Daten - wir brauchen eine bessere API] (https://github.com/kennethreitz/requests/issues/935) angesprochen, um dies zu beheben. Wenn Sie zustimmen, dass die Verwendung des Parameters 'files' zum Senden von Multitpart-Daten bestenfalls irreführend ist, bitten Sie bitte, die API in dem obigen Problem zu ändern. –
@ PiotrDobrogost dieses Problem ist geschlossen. Ermutigen Sie die Leute nicht dazu, sich zu geschlossenen oder relevanten Themen zu äußern. –