【问题标题】:python requests - POST Multipart/form-data without filename in HTTP requestpython请求-在HTTP请求中POST多部分/表单数据没有文件名
【发布时间】:2014-06-01 00:09:35
【问题描述】:

我正在尝试使用 python 中的 requests 模块复制以下 POST 请求:

POST /example/asdfas HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------241652170216373
Content-Length: 279

-----------------------------241652170216373
Content-Disposition: form-data; name="value_1"

12345
-----------------------------241652170216373
Content-Disposition: form-data; name="value_2"

67890
-----------------------------241652170216373--

requests 的文档建议应该使用 files 参数。

当我尝试以下调用时:

import requests
requests.post('http://example.com/example/asdfas', files={'value_1': '12345', 
                                                          'value_2': '67890'})

我收到以下 HTTP 请求:

'Accept': '*/*', 
'Accept-Encoding': 'gzip, deflate, compress', 
'Content-Length': '264', 
'User-Agent': 'python-requests/2.2.1 CPython/3.3.2 Windows/7', 
'Content-Type': 'multipart/form-data; boundary=273f13699c02429db4eb95c97f757d38'
--273f13699c02429db4eb95c97f757d38
Content-Disposition: form-data; name="value_1"; filename="value_1"

12345
--273f13699c02429db4eb95c97f757d38
Content-Disposition: form-data; name="value_2"; filename="value_2"

67890
--273f13699c02429db4eb95c97f757d38--

我也尝试过使用 data 参数:

import requests
requests.post('http://example.com/example/asdfas', data={'value_1': '12345', 
                                                         'value_2': '67890'})

产生以下 HTTP 请求:

'Content-Type': 'application/x-www-form-urlencoded', 
'Content-Length': '27', 
'User-Agent': 'python-requests/2.2.1 CPython/3.3.2 Windows/7', 
'Accept': '*/*', 
'Accept-Encoding': 'gzip, deflate, compress'
value_2=67890&value_1=12345

我遇到的问题是,使用 files 参数会导致服务器无法识别调用,这可能是由于 HTTP 请求中发送了意外的“文件名”信息。使用 data 参数会发送错误的 Content-Type 标头。

已知第一个请求正在我希望将请求发送到的服务器上运行 - 正确复制第一个 HTTP 请求的函数调用是什么?

编辑: 用于复制工作请求的示例 HTML 表单:

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <form action="http://example.com/example/asdfas" method="post" enctype="multipart/form-data">
        <label for="v1">Value 1</label>
        <input id="v1" type="text" name="value_1">
        <label for="v2">Value 2</label>
        <input id="v2" type="text" name="value_2">
        <input type="submit">
    </form>
</body>
</html>

【问题讨论】:

  • 这看起来不太好form...如果您尝试:requests.post('http://example.com/example/asdfas', data={'name': '12345'}) 会发生什么?服务器是做什么的?
  • 表格可能不标准。我已经包含了创建工作请求所需的 HTML。服务器在成功时返回 XML 或在失败时返回 URL not found 服务器错误。

标签: python http python-requests


【解决方案1】:

解决方法是在给files参数传递参数时使用元组:

import requests
requests.post('http://example.com/example/asdfas', files={'value_1': (None, '12345'), 'value_2': (None, '67890')})

按预期工作:

'Accept': '*/*', 
'Accept-Encoding': 'gzip, deflate, compress', 
'Content-Length': '228', 
'User-Agent': 'python-requests/2.2.1 CPython/3.3.2 Windows/7', 
'Content-Type': 'multipart/form-data; boundary=85e90a4bbb05474ca1e23dbebdd68ed9'

--85e90a4bbb05474ca1e23dbebdd68ed9
Content-Disposition: form-data; name="value_1"

12345
--85e90a4bbb05474ca1e23dbebdd68ed9
Content-Disposition: form-data; name="value_2"

67890
--85e90a4bbb05474ca1e23dbebdd68ed9--

【讨论】:

  • 不错的收获!您应该将您的解决方案标记为已接受! (我不知道你可以这样欺骗requests 模块):-)
  • @BorrajaX 嘿,这不是在愚弄我们,它只是我们 API 的一个未记录的角落。在我们更清楚地记录它之前,我们正在尝试确定我们是否对此感到满意。您可以使用 2 到 4 之间任意长度的元组,它会影响多部分主体的不同部分。
  • @sornars 包括提到的类型,我也有,------WebKitFormBoundaryGTNXgIPxfTWUu45A Content-Disposition: form-data; name="files[]"; filename="myvideo.mp4" Content-Type: video/mp4 ------WebKitFormBoundaryGTNXgIPxfTWUu45A-- 如何传递参数?请帮忙
  • 天哪,谢谢!您解决了开始成为主要问题的问题
  • 元组None的第一个元素是什么意思?就我而言,我有这样的数据Content-Disposition: form-data; name="TtsParameter"; paramName="TEXT_TO_READ" 以及如何发布?
【解决方案2】:
import requests
from requests_toolbelt import MultipartEncoder

url = 'http://example.com/example/asdfas'
fields = {'value_1':'12345', 'value_2': '67890'}

data = MultipartEncoder(fields=fields)
headers["Content-type"] = m.content_type

requests.post(url=url, data=data, headers=headers)

【讨论】:

    猜你喜欢
    • 2019-02-19
    • 2017-10-05
    • 2012-11-27
    • 2016-06-29
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 1970-01-01
    相关资源
    最近更新 更多