【问题标题】:python send http request with multiple parameters with same namepython发送具有多个同名参数的http请求
【发布时间】:2026-02-05 14:25:01
【问题描述】:

我需要使用带有 python 的 POST 方法向远程服务器发送一个简单的表单。 这种形式有点奇怪...有些字段名称重复而不使用 [] 而是只传递 key=value 对(这是必需的,否则服务器端的过程不起作用!)。

下面是原始表格的示例:

  <form method="post" action="/remote/test.php">
    <input type=hidden name="value01" value="7777" size="12" maxlength=20>
    <input type="text" name="value02" value="123456789">
    <input type="text" name="value03" value="A1234">
    <input type="text" name="value04" value="B5678">
    <input type=submit value="value05 " class="button">
    <input type="hidden" name="VALUE00" value="9999">
    <input type=hidden name="VALUE99"value="09.01.2015 14:52:40">
    <input type="hidden" name="LIST" value="D0000000033039">
    <input type="hidden" name="LIST" value="D0000000033039">
    <input type="hidden" name="LIST" value="C0000000032032">
    <input type="hidden" name="LIST" value="X0000000031820">    
  </form>

我使用“请求”,根据文档,我可以传递一个字典来发送帖子参数。 所以我实现了下面的代码。填充 sourceDataList 变量的真实数据是从具有 Windows EOL (CR+LF) 的文本文件中读取的,因此为了“模拟”此示例的文件,我编译了一个列表,其值类似于存在于文件

import re

sourceDataList = [
 '2017-12-20 08:59:17;Value01\r\n',
 '2017-12-20 08:59:18;Value02\r\n', 
 '2017-12-20 08:59:20;Value03\r\n',
 '2017-12-20 08:59:21;Value04\r\n'
]
dataList = [];
for line in sourceDataList:
  dataList.append({'RESULT' , re.sub('[^A-Za-z0-9]+', '', line.split(';')[1].strip())});

print dataList;

问题从这里开始......当我打印 dataList 时,我发现数据以一种奇怪的方式“混合”......有时键和值之间存在交换!

例如,上面的代码产生如下结果:

[
 set(['Value01', 'RESULT']), 
 set(['RESULT', 'Value02']), 
 set(['RESULT', 'Value03']), 
 set(['Value04', 'RESULT'])
]

我哪里做错了?

- 更新 1 -

我的目的是创建一个可以与“请求”一起使用的字典。 如果我使用上述设置调用按预期工作并将数据发送到服务器但顺序错误(某些键和值反转)

如果我使用这样的真正字典(请注意,现在我使用 : 代替 , ):

  for line in sourceDataList:
      dataList.append({'RESULT' : re.sub('[^A-Za-z0-9]+', '', line.split(';')[1].strip())});

并将其用作“请求”的参数:

r = requests.post(url, data=dataToSend);

我收到一个错误:

  File "test.py", line 46, in <module>
    r = requests.post(url, data=dataToSend);
  File "C:\Python27\lib\site-packages\requests\api.py", line 112, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "C:\Python27\lib\site-packages\requests\api.py", line 58, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 494, in request
    prep = self.prepare_request(req)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 437, in prepare_request
    hooks=merge_hooks(request.hooks, self.hooks),
  File "C:\Python27\lib\site-packages\requests\models.py", line 308, in prepare
    self.prepare_body(data, files, json)
  File "C:\Python27\lib\site-packages\requests\models.py", line 499, in prepare_body
    body = self._encode_params(data)
  File "C:\Python27\lib\site-packages\requests\models.py", line 97, in _encode_params
    for k, vs in to_key_val_list(data):
ValueError: need more than 1 value to unpack

【问题讨论】:

  • 您希望dataList 看起来如何?
  • 您可以删除与您的问题完全无关的表单和HTTP请求相关的代码。并且应该在后面的代码中更多地解释这个问题。

标签: python forms dictionary post request


【解决方案1】:

在这里,您将数据存储为setPython 中的集合本质上是无序的。 {a, b}(此处注意逗号,)是set 的语法。可能您希望将其存储为 dict(如果您希望将其作为键值对),其语法为 {a: b}(注意这里的冒号 : 而不是 ,)。或者,您也可以将其存储为tuple

例如:

import re

sourceDataList = [
     '2017-12-20 08:59:17;Value01\r\n',
      '2017-12-20 08:59:18;Value02\r\n',
      '2017-12-20 08:59:20;Value03\r\n',
      '2017-12-20 08:59:21;Value04\r\n'
]

# --- Using Dictionary ---
dataList = []
for line in sourceDataList:
    dataList.append({'RESULT' : re.sub('[^A-Za-z0-9]+', '', line.split(';')[1].strip())})

# --- Using tuple ---
dataList = []
for line in sourceDataList:
    dataList.append(('RESULT', re.sub('[^A-Za-z0-9]+', '', line.split(';')[1].strip())))

以下是获得相同结果的单行代码:

# For Dictionary 
dataList = [{'RESULT' : re.sub('[^A-Za-z0-9]+', '', line.split(';')[1].strip())} for line in sourceDataList]

# For Dictionary 
dataList = [('RESULT', re.sub('[^A-Za-z0-9]+', '', line.split(';')[1].strip())) for line in sourceDataList]

以下是您将收到的结果示例:

# --- For Dictionary ---
[{'RESULT': 'Value01'}, {'RESULT': 'Value02'}, {'RESULT': 'Value03'}, {'RESULT': 'Value04'}]

# --- For tuple ---
[('RESULT', 'Value01'), ('RESULT', 'Value02'), ('RESULT', 'Value03'), ('RESULT', 'Value04')]

【讨论】:

    【解决方案2】:

    经过一些测试和阅读大量有关请求的文档后,我终于找到了解决我的具体问题的方法。 总而言之,我需要使用带有一个参数的 POST 方法将一些数据发送到网址。该参数可以包含具有相同字段名称的不同数据。 例如: TESTFIELD= test01, TESTFIELD= test02

    等等..

    现在,可以使用以下语法解决问题:

    import re
    
    def sendData():
    
    
      sourceDataList = [
        '2017-12-20 08:59:17;Value01\r\n',
        '2017-12-20 08:59:18;Value02\r\n', 
        '2017-12-20 08:59:20;Value03\r\n',
        '2017-12-20 08:59:21;Value04\r\n'
       ]
    
      dataList = [];
      for line in sourceDataList:
        dataList.extend([re.sub('[^A-Za-z0-9]+', '', line.split(';')[1].strip())]);
      return {'TESTFIELD': dataList}
    

    这个函数返回下面的字典:

    {'TESTFIELD': ['test01', 'test02', 'test03', 'test04']}

    该请求在 POST 正文中转换,如下所示:

    TESTFIELD=test01&TESTFIELD=test02&TESTFIELD=test03&TESTFIELD=test04

    最终警告!这是特定用例,其中字段名称必须始终相同,这意味着服务器端代码也必须能够读取此特定设置。我必须使用这个不是我做的服务,我不能在服务器端改变任何东西,所以我需要找到这个解决方案。 传递具有相同字段名称的多个值的正确方法是使用 []。 例如:

    TESTFIELD[] = test01, TESTFIELD[] = test02 以此类推……

    这会在服务器端返回一个数组。相反,如果您使用此解决方案,某些服务器端语言无法使用标准函数处理它。

    例如,对于 PHP,您不能依赖 $_POST 超全局变量,您将始终只能找到一个值,因为这是为相同参数传递多个值的非标准方式。 如果你使用 PHP,你必须使用 file_get_contents("php://input") 来获取所有的值,你必须自己解析它。

    【讨论】:

      最近更新 更多