分类讨论 硬编码值("Hardcoding") 和 环境依赖值("Environment-Specific")
简单先陈述一下,按照题主展示的那一部分的代码情况:
如果要获取 对象数据 推荐使用 2.词法分析
如果要获取 "window" 等运行时才存在的变量 只能 使用 3.环境编译
如果嫌麻烦,可以直接使用最后一种方法,因为是实际运行后获取数值的,所以也是最 通用的
那么下面开始具体分析方案
硬编码
即在静态的代码中定义的变量,这种相对容易获取,使用词法分析、正则或者其他字符串匹配方法都可以(相对推荐的是 词法分析框架 ,比如 "slimit")
1.正则(简单情况)
字符串匹配,不适合应对代码复杂的情况,但捕获简单的赋值语句还是相对容易的:
import re
js_code = """
var example = "Hello, world!";
let anotherExample = 123;
const MY_CONSTANT = true;
"""
# 匹配 JavaScript 的变量赋值
matches = re.findall(r'(var|let|const)\s+(\w+)\s*=\s*([^;]+);?', js_code)
# 输出提取的变量名和值
for match in matches:
print(f"Type: {match[0]} - Name: {match[1]} - Value: {match[2]}")
最终的输出结果是:
Type: var - Name: example - Value: "Hello, world!"
Type: let - Name: anotherExample - Value: 123
Type: const - Name: MY_CONSTANT - Value: true
2.词法分析
这种方式会真正意义上去 解析 "js" 代码,抽象为 "AST" 语法树,从而应对复杂情况,比如 "slimit" 框架
这种情况比较适用于捕获复杂的数据类型或者在复杂语句结构里的变量
from slimit.parser import Parser
from slimit.visitors.nodevisitor import ASTVisitor
text = """
var x = {
"key1": "value1",
"key2": "value2"
};
"""
class MyVisitor(ASTVisitor):
def visit_Object(self, node):
"""Visit object literal."""
for prop in node:
left, right = prop.left, prop.right
print('Property key=%s, value=%s' % (left.value, right.value))
# visit all children in turn
self.visit(prop)
parser = Parser()
tree = parser.parse(text)
visitor = MyVisitor()
visitor.visit(tree)
环境依赖(通用)
如果需要捕获一些运行时才存在的值,比如 "windows" 对象,"BOM"、"DOM" 等浏览器接口,那上述做法都没办法生效了
只能考虑运行一下本地浏览器环境获取(比如通过 "selenium"),使用前记得注意浏览器驱动与浏览器版本,还有 "selenium" 的版本,我的是
"4.1.1" :
window.forTest = 10;
let num = 2;
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
# 我的谷歌浏览器不在默认路径,所以需要配置,其他浏览器也有配置方案,参考官方文档即可
chrome_path = r'D:\Google\Chrome\Application\chrome.exe'
o = Options()
o.binary_location = chrome_path
driver = webdriver.Chrome(options=o)
# 可以是绝对路径,也可以是 url
driver.get("file:///xxx.html")
# 获取 JavaScript 运行环境中的变量
window_forTest = driver.execute_script("return window.forTest;")
u = driver.execute_script("return u;")
print(window_forTest)
print(u)
driver.quit()