因打包迁移Puppeteer JS至Selenium Python,求等效Page.exposeFunction()功能
替代Puppeteer exposeFunction()的Selenium Python实现方案
Selenium本身没有和Puppeteer的exposeFunction()完全对等的API,但可以通过以下两种方式实现类似效果:
1. 注入全局JavaScript函数到页面
通过execute_script()将自定义函数挂载到页面的window对象上,直接替换或覆盖页面原有函数,适合修改页面内的逻辑行为。
示例代码(替换页面fetch函数返回伪造数据):
from selenium import webdriver driver = webdriver.Chrome() driver.get("https://example.com") # 注入自定义函数并替换原fetch inject_script = """ window.customFetch = function(url) { return Promise.resolve({ json: () => Promise.resolve({data: "伪造的接口数据"}) }); }; // 覆盖原生fetch window.fetch = window.customFetch; """ driver.execute_script(inject_script) # 验证效果 fake_data = driver.execute_script("return fetch('/api').then(res => res.json())") print(fake_data) # 输出: {'data': '伪造的接口数据'}
注意:这种注入仅对当前页面上下文有效,页面刷新或导航后需要重新执行注入逻辑。如果要在页面加载前注入,可以将浏览器的pageLoadStrategy设为none,先注入脚本再触发页面加载。
2. 利用Chrome DevTools协议(CDP)绑定Python函数到浏览器
通过CDP可以实现浏览器端JavaScript直接调用Python端的函数,更接近exposeFunction()的跨上下文调用能力。
示例代码(绑定Python函数供浏览器调用):
from selenium import webdriver import json driver = webdriver.Chrome() driver.execute_cdp_cmd("Runtime.enable", {}) # 定义Python端处理函数 def process_in_python(input_str): return f"Python处理后的结果: {input_str}" # 封装暴露函数的逻辑 def expose_python_func(func_name, func): def handle_binding_call(message): # 解析浏览器传来的参数 args = json.loads(message["params"]["arguments"]) # 执行Python函数 result = func(*args) # 将结果返回给浏览器 driver.execute_cdp_cmd( "Runtime.callFunctionOn", { "executionContextId": message["params"]["executionContextId"], "functionDeclaration": f"() => {json.dumps(result)}", "objectId": message["params"]["objectId"], } ) # 监听CDP的绑定调用事件 driver.add_listener( lambda msg: handle_binding_call(msg) if msg["method"] == "Runtime.bindingCalled" else None, "Runtime.bindingCalled" ) # 向浏览器注册绑定函数 driver.execute_cdp_cmd("Runtime.addBinding", {"name": func_name}) # 暴露Python函数给浏览器 expose_python_func("callPython", process_in_python) # 在浏览器中调用该函数 result = driver.execute_script("return callPython('测试输入')") print(result) # 输出: Python处理后的结果: 测试输入
这种方式支持浏览器与Python端的双向交互,但需要处理CDP的事件回调逻辑,实现相对复杂。
内容的提问来源于stack exchange,提问作者regomodo
相关产品推荐
相关产品推荐

