Bagaimana cara mengirim multipart/form-data
permintaan dengan python? Cara mengirim file, saya mengerti, tetapi cara mengirim data formulir dengan metode ini tidak bisa mengerti.
python
python-2.7
multipartform-data
python-requests
agrynchuk
sumber
sumber
files
parameter yang digunakan untuk melakukan keduanya adalah API yang sangat buruk. Saya mengangkat masalah berjudul Mengirim data multi-bagian - kita perlu API yang lebih baik untuk memperbaikinya. Jika Anda setuju bahwa menggunakanfiles
parameter untuk mengirim data mulitpart paling menyesatkan, silakan minta untuk mengubah API dalam masalah di atas.Jawaban:
Pada dasarnya, jika Anda menentukan
files
parameter (kamus), makarequests
akan mengirimmultipart/form-data
POST bukannyaapplication/x-www-form-urlencoded
POST. Namun, Anda tidak terbatas menggunakan file aktual dalam kamus itu:dan httpbin.org memberi tahu Anda tajuk apa yang Anda poskan; di
response.json()
kita miliki:Lebih baik lagi, Anda dapat lebih mengontrol nama file, tipe konten, dan header tambahan untuk setiap bagian dengan menggunakan tuple alih-alih objek string atau byte tunggal. Tuple diharapkan mengandung antara 2 dan 4 elemen; nama file, konten, opsional jenis konten, dan kamus opsional header lebih lanjut.
Saya akan menggunakan formulir tuple dengan
None
sebagai nama file, sehinggafilename="..."
parameternya dihapus dari permintaan untuk bagian-bagian itu:files
juga bisa menjadi daftar dua nilai tupel, jika Anda perlu memesan dan / atau beberapa bidang dengan nama yang sama:Jika Anda menentukan baik
files
dandata
, maka itu tergantung pada nilai daridata
apa yang akan digunakan untuk membuat tubuh POST. Jikadata
sebuah string, hanya itu yang akan digunakan; jika tidak keduanya digunakandata
danfiles
digunakan, dengan elemen-elemen yangdata
tercantum terlebih dahulu.Ada juga
requests-toolbelt
proyek unggulan , yang mencakup dukungan Multipart tingkat lanjut . Dibutuhkan definisi bidang dalam format yang sama denganfiles
parameter, tetapi tidak sepertirequests
itu, standarnya adalah tidak menyetel parameter nama file. Selain itu, ia dapat mengalirkan permintaan dari objek file terbuka, di manarequests
pertama-tama akan membangun tubuh permintaan dalam memori:Fields mengikuti konvensi yang sama; gunakan tuple dengan antara 2 dan 4 elemen untuk menambahkan nama file, tipe tajuk atau tajuk ekstra. Berbeda dengan
files
parameter, tidak ada upaya yang dilakukan untuk menemukanfilename
nilai default jika Anda tidak menggunakan tuple.sumber
multipart/form-data
Jenis-Konten harus menyertakan nilai batas yang digunakan untuk menghapus bagian-bagian di badan pos. Tidak mengaturContent-Type
tajuk memastikan bahwarequests
set ke nilai yang benar.multipart/form-data
olah nilai darifiles=
kebenaran, jadi jika Anda perlu mengirimmultipart/form-data
permintaan tetapi tidak termasuk file apa pun, Anda dapat menetapkan nilai yang benar tetapi tidak berarti seperti{'':''}
, dan diaturdata=
dengan badan permintaan Anda. Jika Anda melakukan ini, jangan berikanContent-Type
tajuk sendiri;requests
akan mengaturnya untuk Anda. Anda dapat melihat kebenarannya di sini: github.com/psf/requests/blob/…files
dikt, mereka tidak harus berupa file (pastikan untuk menggunakan formulir tuple dan atur nama file keNone
). Lebih baik lagi, gunakanrequests_toolbelt
proyek.Karena jawaban sebelumnya ditulis, permintaan telah berubah. Lihat utas bug di Github untuk lebih detail dan komentar ini sebagai contoh.
Singkatnya, parameter file mengambil
dict
dengan kunci menjadi nama bidang formulir dan nilainya berupa string atau tuple 2, 3 atau 4-panjang, seperti yang dijelaskan di bagian POST File Multipart-Encoded dalam permintaan mulai cepat:Di atas, tupel terdiri sebagai berikut:
Jika nilainya hanya string, nama file akan sama dengan kunci, seperti berikut ini:
Jika nilainya tupel dan entri pertama adalah
None
properti nama file tidak akan disertakan:sumber
name
danfilename
tetapi juga memiliki beberapa bidang dengan nama yang sama?files
tuple tidak berfungsi lagi: Anda harus menggunakanrequests.post
data
parameter alih-alih mengirimmultipart/form-data
parameter non-file tambahanNone
alih-alih seutas tali kosong sepertinya berhasilAnda perlu menggunakan
files
parameter untuk mengirim permintaan POST bentuk multi-bagian bahkan ketika Anda tidak perlu mengunggah file apa pun.Dari sumber permintaan asli :
Bagian yang relevan adalah:
file-tuple can be a
2-tuple
, .3-tuple
or a
4-tuple
Berdasarkan hal di atas, permintaan formulir multi-bagian paling sederhana yang mencakup file untuk diunggah dan bidang formulir akan terlihat seperti ini:
☝ Catat
None
sebagai argumen pertama dalam tupel untuk bidang teks biasa - ini adalah penampung untuk bidang nama file yang hanya digunakan untuk unggahan file, tetapi untuk bidang teks yang lewatNone
karena parameter pertama diperlukan agar data yang akan dikirim .Beberapa bidang dengan nama yang sama
Jika Anda perlu memposting beberapa bidang dengan nama yang sama, alih-alih sebagai kamus, Anda dapat menentukan payload Anda sebagai daftar (atau tuple) dari tuple:
API permintaan streaming
Jika API di atas tidak cukup pythonic untuk Anda, maka pertimbangkan untuk menggunakan permintaan toolbelt (
pip install requests_toolbelt
) yang merupakan perpanjangan dari modul permintaan inti yang menyediakan dukungan untuk streaming unggah file serta MultipartEncoder yang dapat digunakan sebagai penggantifiles
, dan yang juga memungkinkan Anda mendefinisikan payload sebagai kamus, tuple atau daftar.MultipartEncoder
dapat digunakan baik untuk permintaan multi bagian dengan atau tanpa bidang unggahan yang sebenarnya. Itu harus ditugaskan kedata
parameter.Jika Anda perlu mengirim beberapa bidang dengan nama yang sama, atau jika urutan bidang isian penting, maka tupel atau daftar dapat digunakan sebagai pengganti kamus:
sumber
file.py
berada di folder yang sama dengan skrip Anda.None
bukannya string kosong. Maka permintaan tidak akan menyertakan nama file sama sekali. Jadi, bukannyaContent-Disposition: form-data; name="action"; filename=""
itu akan terjadiContent-Disposition: form-data; name="action"
. Ini penting bagi saya bagi server untuk menerima bidang-bidang itu sebagai bidang formulir dan bukan sebagai file.Berikut ini cuplikan kode sederhana untuk mengunggah satu file dengan parameter tambahan menggunakan permintaan:
Harap perhatikan bahwa Anda tidak perlu secara spesifik menentukan jenis konten apa pun.
CATATAN: Ingin mengomentari salah satu jawaban di atas tetapi tidak dapat karena reputasi rendah sehingga menyusun tanggapan baru di sini.
sumber
Anda perlu menggunakan
name
atribut file unggahan yang ada dalam HTML situs. Contoh:Kamu lihat
name="image">
? Anda dapat menemukannya di HTML situs untuk mengunggah file. Anda harus menggunakannya untuk mengunggah fileMultipart/form-data
naskah:
Di sini, di tempat gambar, tambahkan nama file unggahan dalam HTML
Jika unggahan perlu mengklik tombol untuk unggah, Anda dapat menggunakan seperti itu:
Kemudian mulailah permintaan itu
Dan selesai, file berhasil diunggah
sumber
Kirim kunci dan nilai multipart / formulir-data
perintah curl:
permintaan python - Permintaan POST yang lebih rumit :
Kirim file data multi-formulir / formulir
perintah curl:
permintaan python - POST File yang Dienkripsi Banyak Bagian :
itu saja.
sumber
Ini adalah potongan python yang Anda butuhkan untuk mengunggah satu file tunggal besar sebagai multipart formdata Dengan NodeJs Multer middleware berjalan di sisi server.
Untuk sisi server, silakan periksa dokumentasi multer di: https://github.com/expressjs/multer di sini field tunggal ('fieldName') digunakan untuk menerima satu file tunggal, seperti pada:
sumber