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

如何在Python中发送带有请求的“多部分/表单-数据”?

燕正德
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个元素;文件名、内容、可选的内容类型和可选的其他头的字典。

我将使用具有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--

文件也可以是两值元组列表,如果需要排序和/或多个同名字段:

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

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

还有出色的requests-toolbelt项目,它包括高级的多部分支持。它采用与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值。

 类似资料:
  • 我想发送一个'Multipart/form-data'字典数据没有文件 但API的回应是: 所以我改变了

  • 我试图复制下面的POST请求使用Python中的请求模块: 请求文档建议使用files参数。 当我尝试以下呼叫: 我得到以下HTTP请求: 我还尝试使用数据参数: 导致以下HTTP请求: 我遇到的问题是,使用files参数会导致服务器无法识别调用,可能是由于HTTP请求中发送了意外的“filename”信息。使用数据参数发送错误的内容类型标题。 已知第一个请求正在我希望将请求发送到的服务器上工作-

  • 我有一个REST api,它接受嵌套json的数据,包括多部分文件 在通过postman测试REST api时,我遇到了问题。 我不知道如何发送我需要的各种类型的数据——多部分/表单数据文件和嵌套的json。 我在其他项目中分别使用了REST,但我无法将它们合并到一个请求中。 要使用多部分/表单数据,我必须在正文中选择表单数据,然后从键字段的下拉列表中选择文件,单击值字段上的选择文件按钮,然后选择

  • 我目前正在使用Chrome Addon Postman-REST客户端轻松创建POST/GET请求。 现在我想调试一个上传脚本,我正在寻找一种方法,使请求编码为“多部分/表单-数据”,这样我也可以发送一个文件。

  • 问题内容: 如何在python中发送带有请求的请求?我了解如何发送文件,但是通过这种方法如何发送表单数据尚不清楚。 问题答案: 基本上,如果你指定参数(字典),则将发送m而不是。你不限于在该词典中使用实际文件,但是: 可以让你知道你发布了哪些标题;在我们有: 更好的是,你可以通过使用元组而不是单个字符串或字节对象来进一步控制每个部分的文件名,内容类型和其他标题。该元组应该包含2到4个元素;文件名,

  • 问题内容: 在Apache Commons HttpClient的3.x版本中,可以进行multipart / form-data POST请求(2004年的示例)。不幸的是,这在HttpClient的4.0版本中不再可能。 对于我们的核心活动“ HTTP”,多部分内容超出了范围。我们很乐意使用由其他项目维护的多部分代码,但我对此一无所知。几年前,我们曾尝试将多部分代码移至commons编解码器,