Selenium JavaScript如何检测页面破损图片并校验请求状态
页面破损图片检测实现方案
针对破损图片测试页面的检测场景,原有代码中调用getAttribute("height")获取的是<img>标签上静态声明的属性值,和图片实际加载状态、渲染尺寸无关,因此所有返回值一致,无法作为判断依据。
以下是两种可落地的判断方案:
方案1:通过图片原生尺寸判断(轻量无额外请求)
图片加载失败时,DOM元素的只读属性naturalWidth和naturalHeight会返回0,正常加载的图片两个属性值均大于0,可通过Selenium注入JS直接获取该属性判断,无需额外发起网络请求:
await driver.get("https://the-internet.herokuapp.com/broken_images"); const elements = await driver.findElements(By.css(".example>img")); for (const element of elements) { // 注入JS判断图片原生尺寸 const isBroken = await driver.executeScript(` return arguments[0].naturalWidth === 0 || arguments[0].naturalHeight === 0 `, element); const imgSrc = await element.getAttribute("src"); console.log(isBroken ? `[破损] ${imgSrc}` : `[正常] ${imgSrc}`); }
注意:如果浏览器给破损图片配置了全局默认占位图,该方案可能存在误判,需要结合HTTP状态码校验提升准确率。
方案2:校验图片请求HTTP状态码(准确率100%)
如果需要获取明确的错误状态码(如404、500、403等),可选择以下两种实现方式:
方式A:监听浏览器网络日志(推荐)
以Chrome/Edge浏览器为例,开启性能日志捕获后,可直接从浏览器的网络请求记录中提取所有图片资源的响应状态码,不需要重复发请求,也不会有跨域、鉴权问题:
const { Builder, By } = require('selenium-webdriver'); const chrome = require('selenium-webdriver/chrome'); // 配置Chrome开启性能日志采集 const options = new chrome.Options(); options.setLoggingPrefs({ performance: 'ALL' }); const driver = await new Builder() .forBrowser('chrome') .setChromeOptions(options) .build(); await driver.get("https://the-internet.herokuapp.com/broken_images"); // 解析网络日志,提取图片请求的状态码 const logs = await driver.manage().logs().get('performance'); const imgStatusMap = new Map(); logs.forEach(log => { const { message: { method, params } } = JSON.parse(log.message); if (method === 'Network.responseReceived' && params.type === 'Image') { imgStatusMap.set(params.response.url, params.response.status); } }); // 遍历页面图片元素匹配状态 const elements = await driver.findElements(By.css(".example>img")); for (const element of elements) { const src = await element.getAttribute("src"); const status = imgStatusMap.get(src); console.log( status >= 400 ? `[破损] 地址:${src},状态码:${status}` : `[正常] 地址:${src},状态码:${status}` ); }
方式B:单独发起请求校验图片地址
如果不想配置浏览器日志,也可以拿到图片src属性后,通过HTTP请求库单独发起请求校验状态码:
const fetch = require('node-fetch'); // 省略打开页面、获取元素的逻辑 for (const element of elements) { const src = await element.getAttribute("src"); // 若页面有登录鉴权,需要把当前页面的cookie带到请求头中避免误判 const response = await fetch(src); if (response.status >= 400) { console.log(`[破损] 地址:${src},状态码:${response.status}`); } }
注意:该方案需要处理跨域、鉴权场景,若图片资源有访问限制,需要同步携带Selenium当前上下文的cookie、请求头,否则会出现403误判。
内容的提问来源于stack exchange,提问作者Dmitry Maslo
相关产品推荐
相关产品推荐

