我需要使用带有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
答案 0 :(得分:1)
您将数据存储为set
。 Python中的集合本质上是无序的。 {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')]
答案 1 :(得分:0)
依旧......
现在,可以使用以下语法解决问题:
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”)来获取所有值,你必须自己解析它。