json 如何将原始javascript对象转换为字典?

oalqel3c  于 2023-03-09  发布在  Java
关注(0)|答案(6)|浏览(209)

当我对某个网站进行屏幕抓取时,我从<script>标签中提取数据。
我得到的数据不是标准的JSON。我不能使用json.loads()

# from
js_obj = '{x:1, y:2, z:3}'

# to
py_obj = {'x':1, 'y':2, 'z':3}

目前,我使用regex将原始数据转换为JSON
但是当我遇到复杂的数据结构时,我感觉很糟糕。
你有更好的解决办法吗?

lskq00tm

lskq00tm1#

∮ ∮ ∮ ∮

import demjson

# from
js_obj = '{x:1, y:2, z:3}'

# to
py_obj = demjson.decode(js_obj)

∮ ∮ ∮ ∮

import chompjs

# from
js_obj = '{x:1, y:2, z:3}'

# to
py_obj = chompjs.parse_js_object(js_obj)

∮ ∮ ∮ ∮

import json, _jsonnet

# from
js_obj = '{x:1, y:2, z:3}'

# to
py_obj = json.loads(_jsonnet.evaluate_snippet('snippet', js_obj))

ast.literal_eval()

import ast

# from
js_obj = "{'x':1, 'y':2, 'z':3}"

# to
py_obj = ast.literal_eval(js_obj)
k10s72fa

k10s72fa2#

使用json5

import json5

js_obj = '{x:1, y:2, z:3}'

py_obj = json5.loads(js_obj)

print(py_obj)

# output
# {'x': 1, 'y': 2, 'z': 3}
laik7k3q

laik7k3q3#

今天下午我也遇到了同样的问题,我终于找到了一个很好的解决方案,那就是JSON5
JSON5的语法更类似于原生JavaScript,因此可以帮助您解析非标准JSON对象。
你可能想看看pyjson5

snvhrwxg

snvhrwxg4#

这可能并不适用于所有地方,但作为开始,这里有一个简单的正则表达式,它应该将键转换为带引号的字符串,以便您可以传递到json.loads中。

In[70] : quote_keys_regex = r'([\{\s,])(\w+)(:)'

In[71] : re.sub(quote_keys_regex, r'\1"\2"\3', js_obj)
Out[71]: '{"x":1, "y":2, "z":3}'

In[72] : js_obj_2 = '{x:1, y:2, z:{k:3,j:2}}'

Int[73]: re.sub(quote_keys_regex, r'\1"\2"\3', js_obj_2)
Out[73]: '{"x":1, "y":2, "z":{"k":3,"j":2}}'
xoshrz7s

xoshrz7s5#

如果系统上有node,可以让它为你计算javascript表达式,并打印字符串化的结果,然后将结果JSON提供给json.loads

def evaluate_javascript(s):
    """Evaluate and stringify a javascript expression in node.js, and convert the
    resulting JSON to a Python object"""
    node = Popen(['node', '-'], stdin=PIPE, stdout=PIPE)
    stdout, _ = node.communicate(f'console.log(JSON.stringify({s}))'.encode('utf8'))
    return json.loads(stdout.decode('utf8'))
unguejic

unguejic6#

不包括对象

json.负载()

  • json.loads()不接受未定义,您必须更改为null
  • json.loads()接受双引号
  • {"foo": 1, "bar": null}

如果你确信你的javascript代码只有键名有双引号,那么就使用这个。

import json

json_text = """{"foo": 1, "bar": undefined}"""
json_text = re.sub(r'("\s*:\s*)undefined(\s*[,}])', '\\1null\\2', json_text)

py_obj = json.loads(json_text)

最后文本求值()

  • ast.literal_eval()不接受未定义,您必须更改为
  • ast.literal_eval()不接受null,您必须更改为None
  • ast.literal_eval()不接受True,您必须更改为True
  • ast.literal_eval()不接受false,您必须更改为False
  • ast.literal_eval()接受单引号和双引号
  • {"foo": 1, "bar": None}{'foo': 1, 'bar': None}
import ast

js_obj = """{'foo': 1, 'bar': undefined}"""
js_obj = re.sub(r'([\'\"]\s*:\s*)undefined(\s*[,}])', '\\1None\\2', js_obj)
js_obj = re.sub(r'([\'\"]\s*:\s*)null(\s*[,}])', '\\1None\\2', js_obj)
js_obj = re.sub(r'([\'\"]\s*:\s*)NaN(\s*[,}])', '\\1None\\2', js_obj)
js_obj = re.sub(r'([\'\"]\s*:\s*)true(\s*[,}])', '\\1True\\2', js_obj)
js_obj = re.sub(r'([\'\"]\s*:\s*)false(\s*[,}])', '\\1False\\2', js_obj)

py_obj = ast.literal_eval(js_obj)

相关问题