【问题标题】:Extract JSON from HTML Script tag with BeautifulSoup in Python在 Python 中使用 BeautifulSoup 从 HTML 脚本标签中提取 JSON
【发布时间】:2019-07-26 06:10:20
【问题描述】:

我有以下 HTML,我应该怎么做才能从变量中提取 JSON:window.__INITIAL_STATE__

<!DOCTYPE doctype html>

<html lang="en">
<script>
                  window.sessConf = "-2912474957111138742";
                  /* <sl:translate_json> */
                  window.__INITIAL_STATE__ = { /* Target JSON here with 12 million characters */};
                  /* </sl:translate_json> */
                </script>
</html>

【问题讨论】:

  • 到目前为止你有什么尝试?
  • 1200万个字符的json都在一行吗?这将大大简化答案。
  • @JeffUK 我尝试从脚本标签中获取所有文本,然后拆分('\n'),但它以某种方式将 JSON 分解为几个子字符串。
  • @solarc 是的,它是单行 JSON。
  • 你的系统中有nodejs吗?

标签: python html json beautifulsoup


【解决方案1】:

gdlmx 的代码是正确的,很有帮助。

from subprocess import check_output
soup = BeautifulSoup(html)
s=soup.find('script')
js = 'window = {};\n'+s.text.strip()+';\nprocess.stdout.write(JSON.stringify(window.__INITIAL_STATE__));'
window_init_state = check_output(['node','temp.js'])

type(window_init_state) 将是 .那么你应该使用以下代码。

jsonData= window_init_state.decode("utf-8")

【讨论】:

    【解决方案2】:

    您可以使用以下 Python 代码来提取 JavaScript 代码。

    soup = BeautifulSoup(html)
    s=soup.find('script')
    js = 'window = {};\n'+s.text.strip()+';\nprocess.stdout.write(JSON.stringify(window.__INITIAL_STATE__));'
    with open('temp.js','w') as f:
        f.write(js)
    

    JS 代码将被写入文件“temp.js”。然后就可以调用node来执行JS文件了。

    from subprocess import check_output
    window_init_state = check_output(['node','temp.js'])
    

    python变量window_init_state包含JS对象window.__INITIAL_STATE__的JSON字符串,可以在python中用JSONDecoder解析。

    示例

    from subprocess import check_output
    import json, bs4
    html='''<!DOCTYPE doctype html>
    
    <html lang="en">
    <script> window.sessConf = "-2912474957111138742";
                      /* <sl:translate_json> */
                      window.__INITIAL_STATE__ = { 'Hello':'World'};
                      /* </sl:translate_json> */
                    </script>
    </html>'''
    soup = bs4.BeautifulSoup(html)
    with open('temp.js','w') as f:
        f.write('window = {};\n'+
                soup.find('script').text.strip()+
                ';\nprocess.stdout.write(JSON.stringify(window.__INITIAL_STATE__));')
    window_init_state = check_output(['node','temp.js'])
    print(json.loads(window_init_state))
    

    输出:

    {'Hello': 'World'}
    

    【讨论】:

    • 我得到:FileNotFoundError: [WinError 2] 系统无法从 check_output 中找到指定的文件。是否可能由 with open('temp.js','w') as f 引起?
    • 这可能是因为node 程序未包含在您的PATH 环境变量中。你安装成功了吗?
    • 如果您不确定nodejs 的安装位置。你可以在here列出的位置查找。
    • 我还有一个问题,有没有办法避免将js文件写入硬盘,但达到相同的目标?
    • 是的。尝试使用check_output(['node','-e', your_js_script]),其中your_js_script 是一个包含JS 脚本的python 字符串变量。
    猜你喜欢
    • 2023-03-03
    • 2018-06-10
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 2019-06-16
    • 2018-08-01
    • 1970-01-01
    • 2020-12-07
    相关资源
    最近更新 更多