在 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的主要内容,如果未能解决你的问题,请参考以下文章