¿Cómo enviar un multipart/form-datacon solicitudes en python? Entiendo cómo enviar un archivo, pero no puedo entender cómo enviar los datos del formulario por este método.
python
python-2.7
multipartform-data
python-requests
agrynchuk
fuente
fuente

filesparámetro se use para hacer ambas cosas es una API muy mala. Planteé el problema titulado Envío de datos de varias partes: necesitamos una mejor API para solucionar esto. Si acepta que el uso defilesparámetros para enviar datos de varias partes es engañoso en el mejor de los casos, solicite cambiar la API en el problema anterior.Respuestas:
Básicamente, si especifica un
filesparámetro (un diccionario),requestsenviará unamultipart/form-dataPOST en lugar de unaapplication/x-www-form-urlencodedPOST. Sin embargo, no está limitado a usar archivos reales en ese diccionario:y httpbin.org te permite saber con qué encabezados publicaste; en
response.json()tenemos:Mejor aún, puede controlar aún más el nombre de archivo, el tipo de contenido y los encabezados adicionales para cada parte mediante el uso de una tupla en lugar de una sola cadena o un objeto de bytes. Se espera que la tupla contenga entre 2 y 4 elementos; el nombre de archivo, el contenido, opcionalmente un tipo de contenido y un diccionario opcional de encabezados adicionales.
Usaría el formulario de tupla
Nonecomo nombre de archivo, de modo que elfilename="..."parámetro se elimine de la solicitud de esas partes:filesTambién puede ser una lista de tuplas de dos valores, si necesita ordenar y / o múltiples campos con el mismo nombre:Si especifica ambos
filesydata, entonces depende del valor dedatalo que se utilizará para crear el cuerpo POST. Sidataes una cadena, solo se usará; de lo contrario, ambosdatayfilesse usan, con los elementosdataenumerados primero.También está el excelente
requests-toolbeltproyecto, que incluye soporte avanzado de múltiples partes . Toma definiciones de campo en el mismo formato que elfilesparámetro, pero a diferenciarequests, no establece un parámetro de nombre de archivo. Además, puede transmitir la solicitud desde objetos de archivos abiertos, donderequestsprimero construirá el cuerpo de la solicitud en la memoria:Los campos siguen las mismas convenciones; use una tupla con entre 2 y 4 elementos para agregar un nombre de archivo, parte tipo mime o encabezados adicionales. A diferencia del
filesparámetro, no se intenta encontrar unfilenamevalor predeterminado si no usa una tupla.fuente
multipart/form-dataTipo de contenido debe incluir el valor límite utilizado para delinquir las partes en el cuerpo de la publicación. No establecer elContent-Typeencabezado asegura que serequestsestablece en el valor correcto.multipart/form-datasi el valor defiles=es verdadero, por lo que si necesita enviar unamultipart/form-datasolicitud pero no incluye ningún archivo, puede establecer un valor verdadero pero sin sentido como{'':''}, y establecerlodata=con su cuerpo de solicitud. Si está haciendo esto, no proporcione elContent-Typeencabezado usted mismo;requestslo configurará para ti. Puedes ver la verdad aquí: github.com/psf/requests/blob/…filesdict, no tienen que ser archivos (solo asegúrese de usar el formulario de tupla y establecer el nombre de archivo enNone). Mejor aún, use elrequests_toolbeltproyecto.Desde que se escribieron las respuestas anteriores, las solicitudes han cambiado. Eche un vistazo al hilo de errores en Github para obtener más detalles y este comentario como ejemplo.
En resumen, el parámetro de archivos toma un
dictcon la clave que es el nombre del campo de formulario y el valor es una cadena o una tupla de 2, 3 o 4 longitudes, como se describe en la sección PUBLICAR un archivo codificado en varias partes en las solicitudes Inicio rápido:En lo anterior, la tupla se compone de la siguiente manera:
Si el valor es solo una cadena, el nombre del archivo será el mismo que la clave, como se muestra a continuación:
Si el valor es una tupla y la primera entrada es
Nonela propiedad del nombre de archivo no se incluirá:fuente
nameyfilenamepero también tener múltiples campos con el mismo nombre?filestupla ya no funciona: es necesario utilizarrequests.postdataparámetro en lugar de enviar archivos no additionnalmultipart/form-dataparámetrosNonelugar de una cadena vacía parece funcionarDebe usar el
filesparámetro para enviar una solicitud POST de formulario multiparte incluso cuando no necesite cargar ningún archivo.De la fuente original de solicitudes :
La parte relevante es:
file-tuple can be a2-tuple,3-tupleor a4-tuple.Con base en lo anterior, la solicitud de formulario multiparte más simple que incluye tanto archivos para cargar como campos de formulario se verá así:
☝ Tenga en cuenta que
Nonees el primer argumento en la tupla para campos de texto sin formato: este es un marcador de posición para el campo de nombre de archivo que solo se usa para cargar archivos, pero para los campos de texto que pasanNonecomo primer parámetro es necesario para que los datos se envíen .Múltiples campos con el mismo nombre.
Si necesita publicar múltiples campos con el mismo nombre, en lugar de un diccionario, puede definir su carga útil como una lista (o una tupla) de tuplas:
API de solicitudes de transmisión
Si la API anterior no es lo suficientemente pitónica para usted, entonces considere usar el toolbelt de solicitudes (
pip install requests_toolbelt), que es una extensión del módulo de solicitudes principales que proporciona soporte para la transmisión de carga de archivos, así como el MultipartEncoder que se puede usar en lugar defiles, y que también permite Usted define la carga útil como un diccionario, tupla o lista.MultipartEncoderse puede usar tanto para solicitudes de varias partes con o sin campos de carga reales. Debe asignarse aldataparámetro.Si necesita enviar varios campos con el mismo nombre, o si el orden de los campos del formulario es importante, puede usar una tupla o una lista en lugar de un diccionario:
fuente
file.pyse encuentra en la misma carpeta que su script.Nonelugar de una cadena vacía. Entonces las solicitudes no incluirán un nombre de archivo en absoluto. Así que en lugar deContent-Disposition: form-data; name="action"; filename=""eso seráContent-Disposition: form-data; name="action". Para mí, esto era fundamental para que el servidor aceptara esos campos como campos de formulario y no como archivos.Aquí está el fragmento de código simple para cargar un solo archivo con parámetros adicionales mediante solicitudes:
Tenga en cuenta que no necesita especificar explícitamente ningún tipo de contenido.
NOTA: Quería comentar una de las respuestas anteriores, pero no pude debido a la baja reputación, por lo que redacté una nueva respuesta aquí.
fuente
Debe usar el
nameatributo del archivo de carga que se encuentra en el HTML del sitio. Ejemplo:Lo ves
name="image">? Puede encontrarlo en el HTML de un sitio para cargar el archivo. Debe usarlo para cargar el archivo conMultipart/form-dataguión:
Aquí, en lugar de la imagen, agregue el nombre del archivo de carga en HTML
Si la carga requiere hacer clic en el botón para cargar, puede usar así:
Entonces comienza la solicitud
Y listo, archivo cargado con éxito
fuente
Enviar clave y valor multiparte / datos de formulario
comando curl:
solicitudes de Python : solicitudes POST más complicadas :
Enviar archivo multipart / form-data
comando curl:
solicitudes de Python : PUBLICA un archivo codificado en varias partes :
eso es todo.
fuente
Aquí está el fragmento de Python que necesita para cargar un archivo único grande como datos de formulario multiparte. Con el middleware NodeJs Multer ejecutándose en el lado del servidor.
Para el lado del servidor, consulte la documentación del multer en: https://github.com/expressjs/multer aquí, el campo single ('fieldName') se usa para aceptar un solo archivo, como en:
fuente