难以将字符串转换为JSON对象以便对其进行urlencode

时间:2017-07-25 18:52:07

标签: python python-3.x

我在将通过我的脚本构建的字符串转换为JSON对象时遇到了一些问题(我正在尝试构建发布数据以向API端点发出post请求)。

我收到以下错误:

bos-mpqpu:config_parse rabdelaz$ python3 lexparse.py
{"__class__":"HttpTestClient","description":"CP Codes","url":"://","serverip":"","method":"GET","enabled":true,"headers":[],"tests":[],"purge":false,"procs":[]}
Traceback (most recent call last):
  File "lexparse.py", line 448, in <module>
print(ast.literal_eval(test_case_ACT_template.substitute({'protocol': "",'host': "", 'path' : "", 'query' : "", 'serverip' : "", 'tests' : ""})))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ast.py", line 85, in literal_eval
return _convert(node_or_string)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ast.py", line 66, in _convert
    in zip(node.keys, node.values))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ast.py", line 65, in <genexpr>
    return dict((_convert(k), _convert(v)) for k, v
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ast.py", line 84, in _convert
    raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Name object at 0x103c50c18>

以下是生成上述内容的代码:

test_case_ACT_template = Template('{"__class__":"HttpTestClient","description":"CP Codes","url":"$protocol://$host$path$query","serverip":"$serverip","method":"GET","enabled":true,"headers":[],"tests":[$tests],"purge":false,"procs":[]}')


print(test_case_ACT_template.substitute({'protocol': "",'host': "", 'path' : "", 'query' : "", 'serverip' : "", 'tests' : ""}))

print(ast.literal_eval(test_case_ACT_template.substitute({'protocol': "",'host': "", 'path' : "", 'query' : "", 'serverip' : "", 'tests' : ""})))

请注意,第一个print语句导致以{"__class__"

开头的输出行

我的总体目标是对我的json字符串进行urlencode,但是在SO上进行一些搜索会让我相信在urlencoding之前我应该​​首先执行ast.literal_eval

最终目标如下:

form_data = {'name' : 'CP Code Demo', 'configfilename' : '1-DR4E2_kona-ion.aws-eu-ssl.template_pm-2', 'type' : 'json', 'script' : urlencode(json.load(post_data))}

post_data是一系列模板替换。

导致我开始研究ast.literal_eval的原始错误如下:

   Traceback (most recent call last):
   File "lexparse.py", line 521, in <module>
form_data = {'name' : 'CP Code Demo', 'configfilename' : '1-DR4E2_kona-ion.aws-eu-ssl.template_pm-2', 'type' : 'json', 'script' : urlencode(post_data)}
   File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/parse.py", line 862, in urlencode
"or mapping object").with_traceback(tb)
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/parse.py", line 854, in urlencode
  raise TypeError
TypeError: not a valid non-string sequence or mapping object

2 个答案:

答案 0 :(得分:1)

为了与问题保持一致,您的Template似乎会生成有效的JSON,因此只需将其解析为Python dict,然后将其提交给urllib.parse.urlencode()即可将其转换为有效的URL参数,例如:

import json
from urllib.parse import urlencode
from string import Template

your_template = Template('{"__class__":"HttpTestClient","description":"CP Codes",'
                         '"url":"$protocol://$host$path$query","serverip":"$serverip",'
                         '"method":"GET","enabled":true,"headers":[],"tests":[$tests],'
                         '"purge":false,"procs":[]}')

post_data = your_template.substitute({'protocol': "",
                                      'host': "",
                                      'path': "",
                                      'query': "",
                                      'serverip': "",
                                      'tests': ""})

form_data = {'name': 'CP Code Demo',
             'configfilename': '1-DR4E2_kona-ion.aws-eu-ssl.template_pm-2',
             'type': 'json',
             'script': urlencode(json.loads(post_data))}

print(form_data)

然后你可以把它喂给你想要的任何东西。我仍然强烈建议解决您的证书问题,而不仅仅是将其与cURL相抵消 - 尝试通过CLI传递大量数据时可能遇到的问题可以轻松解决您遇到的问题体验证书。

答案 1 :(得分:0)

它失败的原因是你没有把握真假。

literal_eval将表达式计算为Python对象,而不是JSON,但具有约束。 Per the docs

  

ast.literal_eval(node_or_string)安全地评估表达式节点或   Unicode或Latin-1编码的字符串,包含Python文字或   容器展示。提供的字符串或节点可能只包含   以下Python文字结构:字符串,数字,元组,列表,   dicts,booleans和None。

     

这可以用于安全地评估包含Python的字符串   来自不受信任来源的值,无需解析值   自己。它无法评估任意复杂性   表达式,例如涉及运算符或索引。

注意它所说的&#34;布尔和无&#34;。在Python中,布尔值是True和False,并且必须大写。你的字符串字面值是真的&#39;和&#39; false&#39;。

你可以采用你的文字表达,直接看到它没有评估的原因:

>>> x = {"__class__":"HttpTestClient","description":"CP Codes","url":"://","serverip":"","method":"GET","enabled":true,"headers":[],"tests":[],"purge":false,"procs":[]}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'true' is not defined

如果您正在尝试评估JSON数据,而不是使用AST模块,则可以考虑使用JSON module