如何在Python中提取JavaScript对象键值时保留值的类型?
提取JavaScript对象并保留原始类型的Python解决方案
因为JavaScript语法和Python存在差异(比如无引号键、true/false布尔值、表达式运算等),ast.literal_eval无法直接解析,以下是几种可行的解决办法:
方法一:使用js2py库(纯Python环境)
js2py可以直接执行JavaScript代码,并自动完成JS到Python的类型映射,适合无Node.js环境的场景。
- 先安装库:
pip install js2py
- 示例代码:
import js2py # 完整JS代码(需要补充变量SEC的定义,根据实际业务场景赋值) js_code = """ const SEC = 1000; const rules = { force_update_cache: true, country: 'gb', override_headers: { 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1', }, navigate_opt: {wait_until: ['domcontentloaded'], timeout: 60*SEC}, } """ # 执行JS代码并获取上下文 context = js2py.EvalJs() context.execute(js_code) # 将JS对象转为Python字典,保留原始类型 rules_py = context.rules.to_dict() # 验证结果和类型 print(rules_py) print(type(rules_py['force_update_cache'])) # 输出 <class 'bool'> print(type(rules_py['navigate_opt']['timeout'])) # 输出 <class 'int'>
方法二:使用execjs库(依赖Node.js)
如果本地有Node.js环境,execjs可以调用Node执行JS代码,通过JSON序列化实现类型转换。
- 先安装库:
pip install execjs
- 示例代码:
import execjs import json # 编写JS代码,最后返回JSON格式的rules对象 js_code = """ const SEC = 1000; const rules = { force_update_cache: true, country: 'gb', override_headers: { 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1', }, navigate_opt: {wait_until: ['domcontentloaded'], timeout: 60*SEC}, } JSON.stringify(rules); """ # 执行JS代码并解析结果 result_str = execjs.compile(js_code).eval() rules_py = json.loads(result_str) # 验证结果 print(rules_py) print(type(rules_py['force_update_cache']))
方法三:预处理JS代码后用ast.literal_eval(适合简单场景)
如果JS对象结构简单,无复杂表达式或特殊语法,可以通过正则替换将JS语法转为Python兼容格式,再用ast.literal_eval解析。
示例代码:
import ast import re # 假设已提取的JS键值内容 js_content = """ force_update_cache: true, country: 'gb', override_headers: { 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1', }, navigate_opt: {wait_until: ['domcontentloaded'], timeout: 60*1000}, """ # 1. 给无引号的键添加引号 js_content = re.sub(r'(\w+):', r'"\1":', js_content) # 2. 替换JS布尔值为Python布尔值 js_content = js_content.replace('true', 'True').replace('false', 'False') # 3. 替换JS null为Python None(如果有需要) js_content = js_content.replace('null', 'None') # 包裹成Python字典字符串并解析 py_dict_str = f"{{{js_content}}}" rules_py = ast.literal_eval(py_dict_str) print(rules_py)
注意:这种方法局限性大,若JS键包含特殊字符、存在复杂嵌套或动态表达式,容易解析失败,仅适合固定结构的简单对象。
内容的提问来源于stack exchange,提问作者Adam Rashbi Izrailov
相关产品推荐
相关产品推荐

