Selenium4 Python 页面白屏监控方案

一、安装依赖

bash 复制代码
pip install selenium webdriver-manager

二、核心判断思路(白屏判定规则)

  1. 访问页面,设置页面加载超时
  2. 开启Chrome性能日志,捕获前端Console报错(JS异常是白屏常见诱因)
  3. 使用WebDriverWait等待业务核心根元素 出现
    • ✅ 元素出现:页面渲染正常
    • ❌ 等待超时:大概率白屏/渲染失败
  4. 保存页面快照,留存现场
  5. 收集页面console日志,提取JS错误,写入巡检日志

⚠️ 不要依靠截图像素比对判断白屏(不稳定,不同分辨率、动态样式容易误报);优先DOM元素校验 + JS控制台日志。

三、完整白屏监控脚本

python 复制代码
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, WebDriverException
import logging
import os
from datetime import datetime

# --------------------------配置区--------------------------
WAIT_SECONDS = 10
SCREENSHOT_DIR = "./white_screen_snapshot"
LOG_DIR = "./ws_monitor_log"
# 待监控页面:页面名称、URL、业务根元素定位器(页面正常时一定会渲染的容器)
MONITOR_LIST = [
    {
        "name": "集省受理平台",
        "url": "https://xxx.xxx.com",
        "locator": (By.ID, "app-container")
    }
]
# -----------------------------------------------------------

os.makedirs(SCREENSHOT_DIR, exist_ok=True)
os.makedirs(LOG_DIR, exist_ok=True)

# 日志配置
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s | %(levelname)s | %(message)s",
    handlers=[
        logging.FileHandler(f"{LOG_DIR}/ws_monitor.log", encoding="utf-8"),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)


def get_driver() -> webdriver.Chrome:
    chrome_options = Options()
    chrome_options.add_argument("--headless=new")
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument("--window-size=1920,1080")

    # 开启浏览器日志,捕获Console JS报错
    chrome_options.set_capability("goog:loggingPrefs", {"browser": "ALL"})

    driver = webdriver.Chrome(
        service=Service(ChromeDriverManager().install()),
        options=chrome_options
    )
    driver.set_page_load_timeout(30)
    return driver


def get_browser_console_log(driver: webdriver.Chrome):
    """获取浏览器控制台日志,筛选JS错误"""
    logs = driver.get_log("browser")
    error_list = []
    for entry in logs:
        level = entry["level"]
        msg = entry["message"]
        if level in ("SEVERE", "ERROR"):
            error_list.append(msg)
    return error_list


def save_snapshot(driver, page_name, status):
    ts = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"{SCREENSHOT_DIR}/{page_name}_{status}_{ts}.png"
    try:
        driver.save_screenshot(filename)
        logger.info(f"快照保存:{filename}")
    except Exception as e:
        logger.error(f"截图失败:{str(e)}")


def white_screen_check(page_info: dict):
    page_name = page_info["name"]
    url = page_info["url"]
    locator = page_info["locator"]
    driver = None
    js_errors = []
    try:
        driver = get_driver()
        logger.info(f"开始白屏巡检:{page_name} {url}")
        driver.get(url)

        # 等待业务根容器渲染
        WebDriverWait(driver, WAIT_SECONDS).until(
            EC.presence_of_element_located(locator)
        )
        # 获取控制台日志
        js_errors = get_browser_console_log(driver)
        if js_errors:
            logger.warning(f"页面存在JS报错:{js_errors}")
            save_snapshot(driver, page_name, "js_warn")
        else:
            logger.info(f"✅ {page_name}页面渲染正常,无严重JS错误")
            save_snapshot(driver, page_name, "ok")

    except TimeoutException:
        js_errors = get_browser_console_log(driver)
        logger.error(f"⚠️【疑似白屏】{page_name} 等待业务元素超时,JS错误:{js_errors}")
        if driver:
            save_snapshot(driver, page_name, "white_screen")
    except WebDriverException as e:
        logger.error(f"❌【访问异常】{page_name}: {str(e)}")
        if driver:
            save_snapshot(driver, page_name, "access_error")
    except Exception as e:
        logger.error(f"❌【未知异常】{page_name}: {str(e)}", exc_info=True)
        if driver:
            save_snapshot(driver, page_name, "unknown_error")
    finally:
        if driver:
            driver.quit()


def run_all_check():
    for item in MONITOR_LIST:
        white_screen_check(item)


if __name__ == "__main__":
    run_all_check()

四、白屏判定规则说明(可按需调整告警阈值)

  1. 强告警(判定白屏)
    • 访问页面超时,业务根容器DOM长时间不出现;
    • 页面返回200,但页面只有空白html,app-container 不存在。
  2. 警告(页面可用但有前端异常)
    • 业务DOM渲染成功,但浏览器Console存在SEVERE/ERROR级JS报错,可能局部功能异常。

五、进阶能力扩展

1. 白屏告警(钉钉/企微webhook)

在TimeoutException捕获块内调用,触发告警:

python 复制代码
import requests
def send_alert(page_name, err_info):
    webhook = "https://xxx钉钉webhook"
    payload = {
        "msgtype": "text",
        "text": {"content": f"【白屏告警】页面:{page_name},异常信息:{err_info}"}
    }
    requests.post(webhook, json=payload)

2. 页面加载耗时统计

python 复制代码
# 在driver.get之后执行,获取performance timing
timing = driver.execute_script("return performance.timing;")
load_cost = timing["loadEventEnd"] - timing["navigationStart"]
logger.info(f"页面总加载耗时:{load_cost} ms")
相关推荐
Julien200415 分钟前
管理机密(一)
运维·服务器·开发语言·学习方法
Chen_harmony18 分钟前
七、STL与string类
开发语言·c++
沐晓时光25 分钟前
C语言入门,字符串和字符串函数知识讲解
c语言·开发语言
小小张说故事37 分钟前
Python 的 obj.x 到底按什么顺序找?拆开数据描述符、实例字典和 __getattr__ 那条优先级链
python
xxxiugou12344 分钟前
C++命名空间与引用全解析
开发语言·c++
用户11481867894842 小时前
水印的实现方式逻辑
前端·python
贾公子2 小时前
从单条内容到账号维度——AIGC 风险评分的工程实现
后端·python
yangmu32032 小时前
编程语言发展简史:从机器指令到智能协作
开发语言
木头左3 小时前
【Python】不点浏览器发博客:逆向 CSDN 创作中心接口做 md-publish 技能
python·自动化·api
Tt有了t4 小时前
设计模式速查
java·python·设计模式