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")
相关推荐
y = xⁿ1 小时前
分享一下自己总结的RAG评测流程
人工智能·python
隐退山林1 小时前
JWT令牌技术
java·开发语言·java-ee
全栈弄潮儿1 小时前
Python实战第6期:列表与元组
后端·python·编程语言
日耗10亿Token被老板赶出门1 小时前
大模型接口返回 200,为什么程序还是报错?
python
小小张说故事1 小时前
Python 的 __new__ 到底管什么?和 __init__ 的分工一次讲透Python后端python知识整理日新计划
python
ESDWAN2 小时前
跨境网络延迟、抖动和丢包有什么区别?如何判断业务影响
开发语言·网络·计算机网络·php
Code_Solitude2 小时前
C语言分支结构练习题(华师版)
c语言·开发语言
青少儿编程课堂2 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会C/C++考级:并查集连通块与朋友圈问题解析
c++·python·算法·bfs·信息学竞赛
外收内放2 小时前
数据分析(数据排序)
python·学习·数据分析