当前位置: 首页 > 面试题库 >

如何在python中发送带有请求的“ multipart / form-data”?

姜正初
2023-03-14
问题内容

如何multipart/form-data在python中发送带有请求的请求?我了解如何发送文件,但是通过这种方法如何发送表单数据尚不清楚。


问题答案:

基本上,如果你指定files参数(字典),requests则将发送multipart/form-dataPOST而不是application/x-www-form-urlencodedPOST。你不限于在该词典中使用实际文件,但是:

>>> import requests
>>> response = requests.post('http://httpbin.org/post', files=dict(foo='bar'))
>>> response.status_code
200

httpbin.org可以让你知道你发布了哪些标题;在response.json()我们有:

>>> from pprint import pprint
>>> pprint(response.json()['headers'])
{'Accept': '*/*',
 'Accept-Encoding': 'gzip, deflate',
 'Connection': 'close',
 'Content-Length': '141',
 'Content-Type': 'multipart/form-data; '
                 'boundary=c7cbfdd911b4e720f1dd8f479c50bc7f',
 'Host': 'httpbin.org',
 'User-Agent': 'python-requests/2.21.0'}

更好的是,你可以通过使用元组而不是单个字符串或字节对象来进一步控制每个部分的文件名,内容类型和其他标题。该元组应该包含2到4个元素;文件名,内容,可选的内容类型以及其他标头的可选字典。

我将使用元组形式None作为文件名,以便将filename="..."参数从这些部分的请求中删除:

>>> files = {'foo': 'bar'}
>>> print(requests.Request('POST', 'http://httpbin.org/post', files=files).prepare().body.decode('utf8'))
--bb3f05a247b43eede27a124ef8b968c5
Content-Disposition: form-data; name="foo"; filename="foo"

bar
--bb3f05a247b43eede27a124ef8b968c5--
>>> files = {'foo': (None, 'bar')}
>>> print(requests.Request('POST', 'http://httpbin.org/post', files=files).prepare().body.decode('utf8'))
--d5ca8c90a869c5ae31f70fa3ddb23c76
Content-Disposition: form-data; name="foo"

bar
–d5ca8c90a869c5ae31f70fa3ddb23c76–

files 如果需要排序和/或具有相同名称的多个字段,也可以是二值元组的列表:

requests.post(
    'http://requestb.in/xucj9exu',
    files=(
        ('foo', (None, 'bar')),
        ('foo', (None, 'baz')),
        ('spam', (None, 'eggs')),
    )
)

如果同时指定files和data,然后它取决于价值的data东西将被用于创建POST体。如果data是字符串,则仅使用它将;否则data,files都使用和,并data首先列出元素。

还有一个出色的requests-toolbelt项目,其中包括高级的Multipart支持。它采用与files参数格式相同的字段定义,但是与不同requests,它默认不设置文件名参数。此外,它可以从打开的文件对象流式传输请求,requests首先将在内存中构造请求主体:

from requests_toolbelt.multipart.encoder import MultipartEncoder

mp_encoder = MultipartEncoder(
    fields={
        'foo': 'bar',
        # plain file object, no filename or mime type produces a
        # Content-Disposition header with just the part name
        'spam': ('spam.txt', open('spam.txt', 'rb'), 'text/plain'),
    }
)
r = requests.post(
    'http://httpbin.org/post',
    data=mp_encoder,  # The MultipartEncoder is posted as data, don't use files=...!
    # The MultipartEncoder provides the content-type header with the boundary:
    headers={'Content-Type': mp_encoder.content_type}
)

字段遵循相同的约定;使用包含2到4个元素的元组来添加文件名,部分mime类型或额外的标头。与files参数不同,filename如果不使用元组,则不会尝试查找默认值。



 类似资料:
  • 如何在Python中用请求发送?如何发送文件,我明白了,但是如何用这种方法发送表单数据就不明白了。

  • 我必须使用REST API将文件和信息上传到服务器。该API使用多部分形式,但我似乎无法正确使用它。 null 我尝试了几种方法,比如下面的代码,但是我不断从服务器得到错误的请求。

  • 如何在web服务中读取多部分/表单数据?我发送数据使用邮递员身体形式的数据,但邮递员得到错误。 错误系统。InvalidOperationException:请求格式无效:多部分/表单数据;边界=----WebKitformBoundary79KY1A1KYYY7QUI。at系统。网状物服务。协议。HttpServerProtocol。系统中的ReadParameters()。网状物服务。协议。W

  • 我正试图将一些表单数据文件发送到后端,但我遇到了这个问题,浏览器(或服务器,或其他什么)一直忽略我定义的边界,并将请求负载更改为一些WebKitFormBoundary随机生成的边界。 这是我根据我的要求定义的 <代码>。工厂('FilesPaymentsImportationsUploadResource',函数($resource,PAYMENTS\u API\u URL){返回$资源(PAY

  • 问题内容: 我知道对此有很多疑问,但我无法解决这个问题: 我想将输入中的文件上传到multipart / form-data中的服务器 我尝试了两种方法。第一: 这导致例如图像 它应该是多部分/表单数据 和另外一个: 但这要求一个边界标头,我认为不应手动插入… 解决此问题的干净方法是什么?我读过你可以做的 但是我不希望我的所有帖子都是多部分/表单数据。默认值应为JSON 问题答案: 看一下Form

  • 问题内容: 我正在开发使用不同服务其余部分的图形界面(用Java编写)。我必须调用这样的服务: 呼叫服务: 当我从Angularjs服务文件中请求时,如果服务具有Content-Type = multipart / form- data,则会收到错误400(错误请求) 如果服务的Content-Type =“ application / x-www-form-urlencoded; charset