You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Selenium窗口会话中的JavaScript变量保持持久化?

问题原因

页面刷新、导航跳转或触发页面重载时,浏览器会重置整个window上下文,你之前通过JavaScript Executor注入的变量和XHR Hook都会被清除,因此window.processFlag会变成undefined。

解决方案

方案1:利用Chrome DevTools Protocol(CDP)自动注入Hook代码

这是最可靠的方案,CDP的Page.addScriptToEvaluateOnNewDocument会让你的Hook代码在每个新文档加载的最早期阶段自动执行,覆盖页面刷新、跳转等所有场景,确保XHR Hook和变量始终生效。

Python Selenium示例代码:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait

options = Options()
driver = webdriver.Chrome(options=options)

# 定义Hook脚本
hook_script = """
window.processFlag = -1;
var open = window.XMLHttpRequest.prototype.open,
    send = window.XMLHttpRequest.prototype.send;

function openReplacement(method,url,async,user,password) {
    this._url = url;
    return open.apply(this,arguments);
}

function sendReplacement(data){
    if(this.onreadystatechange){
        this._onreadystatechange = this.onreadystatechange;
    }
    this.onreadystatechange = onReadyStateChangeReplacement;
    window.processFlag = 0;
    return send.apply(this,arguments);
}

function onReadyStateChangeReplacement(){
    window.processFlag = this.readyState;
    if(this._onreadystatechange){
        return this._onreadystatechange.apply(this,arguments);
    }
}

window.XMLHttpRequest.prototype.open = openReplacement;
window.XMLHttpRequest.prototype.send = sendReplacement;
"""

# 通过CDP设置页面加载时自动执行脚本
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": hook_script})

# 访问目标页面
driver.get("your_target_url")

# 自定义WebDriverWait判断逻辑
def check_process_flag(driver):
    return driver.execute_script("return window.processFlag === 4;")

WebDriverWait(driver, 10).until(check_process_flag)

方案2:使用sessionStorage持久化状态

sessionStorage会在同一窗口会话的页面刷新、跳转后保留(关闭窗口才会清除),可以把processFlag存储在这里,避免页面刷新后丢失状态。需要修改Hook脚本的变量读写逻辑:

修改后的Hook脚本:

// 初始化sessionStorage中的状态,不存在则设为-1
if (!sessionStorage.getItem('processFlag')) {
    sessionStorage.setItem('processFlag', '-1');
}

var open = window.XMLHttpRequest.prototype.open,
    send = window.XMLHttpRequest.prototype.send;

function openReplacement(method,url,async,user,password) {
    this._url = url;
    return open.apply(this,arguments);
}

function sendReplacement(data){
    if(this.onreadystatechange){
        this._onreadystatechange = this.onreadystatechange;
    }
    this.onreadystatechange = onReadyStateChangeReplacement;
    sessionStorage.setItem('processFlag', '0');
    return send.apply(this,arguments);
}

function onReadyStateChangeReplacement(){
    sessionStorage.setItem('processFlag', String(this.readyState));
    if(this._onreadystatechange){
        return this._onreadystatechange.apply(this,arguments);
    }
}

window.XMLHttpRequest.prototype.open = openReplacement;
window.XMLHttpRequest.prototype.send = sendReplacement;

对应的WebDriverWait判断逻辑:

def check_process_flag(driver):
    flag = driver.execute_script("return sessionStorage.getItem('processFlag');")
    return int(flag) == 4

WebDriverWait(driver, 10).until(check_process_flag)

注意:此方案需要配合自动注入脚本(比如方案1的CDP方法),否则页面刷新后XHR Hook会失效,仅状态保留无意义。

方案3:页面刷新后手动重新注入脚本

如果无法使用CDP,可在每次页面刷新、导航或触发重载后,手动重新注入Hook脚本:

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

def inject_hook(driver):
    hook_script = """
    window.processFlag = -1;
    var open = window.XMLHttpRequest.prototype.open,
        send = window.XMLHttpRequest.prototype.send;

    // 剩余Hook代码与原脚本一致
    """
    driver.execute_script(hook_script)

# 首次加载页面并注入
driver.get("your_target_url")
inject_hook(driver)

# 刷新页面后重新注入
driver.refresh()
inject_hook(driver)

# 点击元素触发页面重载后,等待页面加载完成再注入
driver.find_element(By.ID, "trigger-refresh-btn").click()
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, "body")))
inject_hook(driver)

此方案缺点是容易遗漏页面重载场景,需额外处理各种可能触发刷新的操作,稳定性不如方案1。


内容的提问来源于stack exchange,提问作者vijay eathakotla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 11:15:33