Cypress谷歌航班自动化:价格条形图遍历点击仅半数生效故障
问题描述
我正在使用Cypress开发谷歌航班自动化脚本,该脚本需遍历代表每日航班价格的条形图,逐一点击每个条形元素。但通过for循环遍历过程中,仅能成功点击半数条形,导致脚本因索引关联逻辑中途停止。例如循环14次才点击第8个条形,点击规律大致为1是、2是、3否、4是、5否等。当前代码如下:
for(let i = indice; i<61; i++){ let fechaSinProcesar = ''; let precio = ''; await lista.locator(graficoDePreciosPage.barraPrecioDiario + '[' + i + ']').click({force : true}); if(await page.locator(graficoDePreciosPage.precioDeVuelo).isVisible()){ precio = await page.locator(graficoDePreciosPage.precioDeVuelo).textContent(); fechaSinProcesar = await page.locator(graficoDePreciosPage.fechaDeVuelo).textContent(); } let fecha = fechaSinProcesar.normalize("NFD").replace(/[\u0300-\u036f]/g, ''); jsonVuelos[fecha] = precio; }
问题原因
- DOM动态更新:点击条形后谷歌航班页面会重新渲染部分元素,导致原索引对应的元素位置偏移,后续循环按固定索引查找时会定位到错误元素。
- 选择器与实际元素不匹配:原代码使用固定索引
[i]定位元素,若页面存在隐藏条形(如无航班的日期),会导致索引与可见元素数量不对应,出现跳点情况。
解决方案
方案一:遍历可见元素集合(推荐)
先获取所有可见的价格条形元素,再逐个遍历操作,避免DOM更新导致的索引错位:
// 筛选出所有可见的每日价格条形元素 const barrasVisibles = lista.locator(graficoDePreciosPage.barraPrecioDiario).filter({ visible: true }); // 获取可见元素的总数量 const totalBarras = await barrasVisibles.count(); for (let i = 0; i < totalBarras; i++) { let fechaSinProcesar = ''; let precio = ''; // 每次通过nth(i)重新定位当前元素,适配DOM变化 await barrasVisibles.nth(i).click({ force: true }); // 等待价格元素加载完成后再获取内容 if (await page.locator(graficoDePreciosPage.precioDeVuelo).isVisible({ timeout: 3000 })) { precio = await page.locator(graficoDePreciosPage.precioDeVuelo).textContent(); fechaSinProcesar = await page.locator(graficoDePreciosPage.fechaDeVuelo).textContent(); } let fecha = fechaSinProcesar.normalize("NFD").replace(/[\u0300-\u036f]/g, ''); jsonVuelos[fecha] = precio; }
方案二:优化原循环的等待逻辑
若坚持使用原索引循环,需在点击后等待页面稳定,确保元素位置不偏移:
for(let i = indice; i<61; i++){ let fechaSinProcesar = ''; let precio = ''; await lista.locator(graficoDePreciosPage.barraPrecioDiario + '[' + i + ']').click({force : true}); // 等待页面DOM稳定或价格元素加载完成 await page.waitForLoadState('domcontentloaded'); await page.locator(graficoDePreciosPage.precioDeVuelo).waitFor({ visible: true, timeout: 5000 }); if(await page.locator(graficoDePreciosPage.precioDeVuelo).isVisible()){ precio = await page.locator(graficoDePreciosPage.precioDeVuelo).textContent(); fechaSinProcesar = await page.locator(graficoDePreciosPage.fechaDeVuelo).textContent(); } let fecha = fechaSinProcesar.normalize("NFD").replace(/[\u0300-\u036f]/g, ''); jsonVuelos[fecha] = precio; }
方案三:校验选择器准确性
检查graficoDePreciosPage.barraPrecioDiario是否精准定位每个独立条形元素,避免包含父容器或隐藏元素。可通过浏览器开发者工具验证选择器,确保仅匹配可见的每日价格条形。
内容的提问来源于stack exchange,提问作者Oto
相关产品推荐
相关产品推荐

