Como enviar um multipart/form-data
com pedidos em python? Como enviar um arquivo, eu entendo, mas como enviar os dados do formulário por este método não consigo entender.
python
python-2.7
multipartform-data
python-requests
agrynchuk
fonte
fonte
files
parâmetro ser usado para fazer as duas coisas é uma API muito ruim. Eu levantei a questão intitulada Enviando dados de várias partes - precisamos de uma API melhor para corrigir isso. Se você concorda que o uso dofiles
parâmetro para enviar dados com várias partes é enganoso, na melhor das hipóteses, solicite a alteração da API na edição acima.Respostas:
Basicamente, se você especificar um
files
parâmetro (um dicionário),requests
enviará ummultipart/form-data
POST em vez de umapplication/x-www-form-urlencoded
POST. Você não está limitado ao uso de arquivos reais nesse dicionário, no entanto:e httpbin.org permite saber em quais cabeçalhos você postou; em
response.json()
que temos:Melhor ainda, você pode controlar ainda mais o nome do arquivo, o tipo de conteúdo e os cabeçalhos adicionais de cada parte usando uma tupla em vez de uma única string ou objeto de bytes. A tupla deve conter entre 2 e 4 elementos; o nome do arquivo, o conteúdo, opcionalmente um tipo de conteúdo e um dicionário opcional de outros cabeçalhos.
Eu usaria o formulário de tupla com
None
o nome do arquivo, para que ofilename="..."
parâmetro seja descartado da solicitação para essas partes:files
também pode ser uma lista de tuplas de dois valores, se você precisar solicitar e / ou vários campos com o mesmo nome:Se você especificar ambos
files
edata
, isso dependerá do valor dodata
que será usado para criar o corpo do POST. Sedata
for uma string, somente ela será usada; caso contrário, ambosdata
efiles
são usados, com os elementosdata
listados primeiro.Há também o excelente
requests-toolbelt
projeto, que inclui suporte avançado a várias partes . Leva definições de campo no mesmo formato que ofiles
parâmetro, masrequests
, ao contrário , o padrão é não definir um parâmetro de nome de arquivo. Além disso, ele pode transmitir a solicitação a partir de objetos de arquivo aberto, onderequests
primeiro construirá o corpo da solicitação na memória:Os campos seguem as mesmas convenções; use uma tupla com entre 2 e 4 elementos para adicionar um nome de arquivo, parte do tipo MIME ou cabeçalhos extras. Diferente do
files
parâmetro, nenhuma tentativa é feita para encontrar umfilename
valor padrão se você não usar uma tupla.fonte
multipart/form-data
Content-Type deve incluir o valor limite usado para delinear as partes no corpo do post. Não definir oContent-Type
cabeçalho garante querequests
ele seja definido com o valor correto.multipart/form-data
se o valor defiles=
fosse verdadeiro; portanto, se você precisar enviar umamultipart/form-data
solicitação, mas não incluir nenhum arquivo, poderá definir um valor verdadeiro, mas sem sentido, como{'':''}
, e definirdata=
com o corpo da solicitação. Se você estiver fazendo isso, não forneça oContent-Type
cabeçalho;requests
irá definir para você. Você pode ver a verificação da verdade aqui: github.com/psf/requests/blob/…files
dict, eles não precisam ser arquivos (use o formulário de tupla e defina o nome do arquivo comoNone
). Melhor ainda, use orequests_toolbelt
projeto.Desde que as respostas anteriores foram escritas, os pedidos foram alterados. Dê uma olhada no tópico do bug no Github para obter mais detalhes e este comentário para um exemplo.
Em resumo, o parâmetro files leva a
dict
com a chave sendo o nome do campo de formulário e o valor sendo uma sequência de caracteres ou uma tupla de 2, 3 ou 4 comprimentos, conforme descrito na seção POST um arquivo codificado por várias partes nas solicitações começo rápido:Acima, a tupla é composta da seguinte maneira:
Se o valor for apenas uma cadeia, o nome do arquivo será o mesmo da chave, como no seguinte:
Se o valor for uma tupla e a primeira entrada for
None
a propriedade filename, não será incluída:fonte
name
efilename
mas também tem vários campos com o mesmo nome?files
tupla não funciona mais: você precisa usarrequests.post
data
parâmetro em vez de enviar non-arquivo additionnalmultipart/form-data
parâmetrosNone
em vez de uma seqüência vazia parece funcionarVocê precisa usar o
files
parâmetro para enviar uma solicitação POST de formulário com várias partes, mesmo quando não precisar fazer upload de nenhum arquivo.Na fonte de solicitações originais :
A parte relevante é:
file-tuple can be a
2-tuple
, .3-tuple
or a
4-tuple
Com base no exposto acima, a solicitação de formulário multipartes mais simples que inclui os arquivos para upload e os campos do formulário será semelhante a:
☝ Observe
None
como o primeiro argumento na tupla para campos de texto sem formatação - este é um espaço reservado para o campo nome do arquivo que é usado apenas para upload de arquivos, mas para campos de texto que passamNone
como o primeiro parâmetro é necessário para que os dados sejam enviados .Vários campos com o mesmo nome
Se você precisar postar vários campos com o mesmo nome, em vez de um dicionário, poderá definir sua carga como uma lista (ou uma tupla) de tuplas:
API de solicitações de streaming
Se a API acima não for suficientemente pitônica para você, considere o uso de orders toolbelt (
pip install requests_toolbelt
), que é uma extensão do módulo de solicitações principais que fornece suporte para streaming de upload de arquivos, bem como o MultipartEncoder que pode ser usado em vez defiles
, e que também permite você define a carga útil como dicionário, tupla ou lista.MultipartEncoder
pode ser usado para solicitações de várias partes com ou sem campos de upload reais. Ele deve ser atribuído aodata
parâmetro.Se você precisar enviar vários campos com o mesmo nome ou se a ordem dos campos do formulário for importante, uma tupla ou uma lista poderá ser usada em vez de um dicionário:
fonte
file.py
esteja localizado na mesma pasta que o seu script.None
vez da string vazia. As solicitações não incluirão um nome de arquivo. Então, ao invés dissoContent-Disposition: form-data; name="action"; filename=""
, seráContent-Disposition: form-data; name="action"
. Isso foi fundamental para mim para o servidor aceitar esses campos como campos de formulário e não como arquivos.Aqui está o trecho de código simples para fazer upload de um único arquivo com parâmetros adicionais usando solicitações:
Observe que você não precisa especificar explicitamente nenhum tipo de conteúdo.
NOTA: Queria comentar uma das respostas acima, mas não pôde, devido à baixa reputação, por isso elaborou uma nova resposta aqui.
fonte
Você precisa usar o
name
atributo do arquivo de upload que está no HTML do site. Exemplo:Você vê
name="image">
? Você pode encontrá-lo no HTML de um site para fazer upload do arquivo. Você precisa usá-lo para fazer upload do arquivo comMultipart/form-data
roteiro:
Aqui, no lugar da imagem, adicione o nome do arquivo de upload em HTML
Se o upload exigir clicar no botão para envio, você poderá usar assim:
Em seguida, inicie a solicitação
E pronto, o arquivo foi enviado com sucesso
fonte
Enviar chave e valor multipart / dados de formulário
comando curl:
requisições python - solicitações POST mais complicadas :
Enviar arquivo multipart / dados de formulário
comando curl:
solicitações python - POST um arquivo codificado por várias partes :
Isso é tudo.
fonte
Aqui está o snippet python necessário para carregar um arquivo único grande como dados de formulário de várias partes. Com o middleware do NodeJs Multer em execução no lado do servidor.
Para o servidor, verifique a documentação do multer em: https://github.com/expressjs/multer aqui, o campo single ('fieldName') é usado para aceitar um único arquivo, como em:
fonte