当前位置: 首页 > 知识库问答 >
问题:

如何在Python中用请求发送“multipart/form-data”?

和斌
2023-03-14

如何在Python中用请求发送multipart/form-data?如何发送文件,我明白了,但是如何用这种方法发送表单数据就不明白了。

共有1个答案

公羊浩阔
2023-03-14

基本上,如果指定files参数(字典),那么requests将发送multipart/form-data帖子,而不是application/x-www-form-urlencoded帖子。但是,您并不局限于使用字典中的实际文件:

>>> 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'}

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

>>> 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--
requests.post(
    'http://requestb.in/xucj9exu',
    files=(
        ('foo', (None, 'bar')),
        ('foo', (None, 'baz')),
        ('spam', (None, 'eggs')),
    )
)

如果同时指定文件数据,则这取决于将用于创建POST正文的data的值。如果data字符串,则只使用它;否则,将使用数据文件数据中的元素首先列出。

还有优秀的requests-toolbelt项目,其中包括高级多部分支持。它采用与files参数相同格式的字段定义,但与requests不同的是,它默认不设置filename参数。此外,它还可以从打开的文件对象流式传输请求,其中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中发送带有请求的请求?我了解如何发送文件,但是通过这种方法如何发送表单数据尚不清楚。 问题答案: 基本上,如果你指定参数(字典),则将发送m而不是。你不限于在该词典中使用实际文件,但是: 可以让你知道你发布了哪些标题;在我们有: 更好的是,你可以通过使用元组而不是单个字符串或字节对象来进一步控制每个部分的文件名,内容类型和其他标题。该元组应该包含2到4个元素;文件名,

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

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

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

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

  • 问题内容: 我在这里尝试做的是获取给定URL的标头,以便确定MIME类型。我希望能够查看是否http://somedomain/foo/将返回例如HTML文档或JPEG图像。因此,我需要弄清楚如何发送HEAD请求,以便无需下载内容就可以读取MIME类型。有人知道这样做的简单方法吗? 问题答案: 使用。 还有一个getheader(name)获取特定的标头。