在 Python 中使用 BeautifulSoup 从 HTML 脚本标签中提取 JSON

Posted

技术标签:

【中文标题】在 Python 中使用 BeautifulSoup 从 HTML 脚本标签中提取 JSON【英文标题】:Extract JSON from HTML Script tag with BeautifulSoup in Python 【发布时间】: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吗? 【参考方案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 字符串变量。

以上是关于在 Python 中使用 BeautifulSoup 从 HTML 脚本标签中提取 JSON的主要内容,如果未能解决你的问题,请参考以下文章

beautifulsoup模块

Beautifulsoup模块

python 抓取图片

python安装Django需要环境

python网络爬虫 - 如何伪装逃过反爬虫程序

[Python3网络爬虫开发实战] 1.3.2-Beautiful Soup的安装