【问题标题】:How to extract JSON from script with Python?如何使用 Python 从脚本中提取 JSON?
【发布时间】:2020-12-20 08:45:26
【问题描述】:

我正在解析一个抓取的 html 页面,其中包含一个带有 JSON 的脚本。此 JSON 包含我正在寻找的所有信息,但我不知道如何提取有效的 JSON。

小例子:

my_string = '
        (function(){
          window.__PRELOADED_STATE__ = window.__PRELOADED_STATE__ || [];
          window.__PRELOADED_STATE__.push(
        
           { *placeholder representing valid JSON inside* }
        );
        })()
'

里面的json根据jsonlinter是有效的。

结果应该被加载到字典中:

import json
import re
my_json = re.findall(r'.*(?={\").*', my_string)[0] // extract json
data = json.loads(my_json)
// print(data)

正则表达式:https://regex101.com/r/r0OYZ0/1

这个尝试的结果是:

>>> data = json.loads(my_json)
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/code.py", line 90, in runcode
    exec(code, self.locals)
  File "<console>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 7 (char 6)

如何使用 Python 3.7.x 从字符串中提取和加载 JSON?

【问题讨论】:

  • 您必须使用json.loads 方法(不要忘记s)。但是您的字符串似乎不是有效的 json。
  • 确实如此,请再次阅读问题。
  • 正则表达式示例中的 JSON 不是有效的 JSON:{"publicRuntimeConfig":{"public }

标签: python json regex


【解决方案1】:

您可以尝试提取此正则表达式,这是一个非常简单的案例,可能无法回答所有可能的 json 变体:

my_string = '''
        (function(){
          window.__PRELOADED_STATE__ = window.__PRELOADED_STATE__ || [];
          window.__PRELOADED_STATE__.push(
        
            {"tst":{"f":3}}
        );
        })()
'''
result = re.findall(r"push\(([{\[].*\:.*[}\]])\)",string3)[0]
result
>>> '{ "tst":{"f":3}}'

现在将其解析为字典:

import json 

dictionary = json.loads(result)
type(dictionary)
>>>dict

【讨论】:

  • 是的,不幸的是,Json 包含转义字符,您知道如何去除转义符号吗?
  • json 包含:["string 5\'-mono.d
  • 我更新了问题并使用完整的 JSON 链接到 regex101
  • 这是因为正则表达式不正确。后视捕捉到了结束语。如果最后删除 ) ,它将根据 jsonlint.com 进行验证
  • 你是对的!看起来我有另一个有效的正则表达式。 .*(?:push()(.*)) 你会推荐使用哪一个?为什么?
【解决方案2】:

请看下面。请注意,{ *placeholder representing valid JSON inside* } 必须是有效的 JSON。

my_string = '''
        <script>
            (function(){
              window.__PRELOADED_STATE__ = window.__PRELOADED_STATE__ || [];
              window.__PRELOADED_STATE__.push(
            
               {"foo":["bar1", "bar2"]}
            );
            })()
         </script>
'''

import re, json

my_json = re.findall(r'.*(?={\").*', my_string)[0].strip()
data = json.loads(my_json)
print(data)

输出:

{'foo': ['bar1', 'bar2']}

【讨论】:

  • 越来越近了。我现在有一个类似的正则表达式:.*(?:push()(.*)(?
  • 也许你可以用str.replace()
【解决方案3】:

此处提供的 my_string 不是有效的 JSON。对于有效的 JSON,您可以使用json.loads(JSON_STRING)

import json

d = json.loads('{"test":2}')
print(d) # Prints the dictionary `{'test': 2}`

【讨论】:

  • 这就是重点!请再次阅读我的问题,“里面的json是有效的”。我需要弄清楚如何删除它周围的 javascript 代码。
  • 在我发布此答案后,对问题进行了编辑以澄清这一点。
  • 是的,看到你的回答后,我试图让事情更清楚。正则表达式可能会有所帮助,有什么想法吗?
猜你喜欢
  • 2019-07-26
  • 2020-07-27
  • 2016-11-23
  • 2016-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 2016-08-27
相关资源
最近更新 更多