使用JavaScript解析多维数组求助(Selenium自动化场景)
解决Selenium抓取IQAir空气质量数据的一维数组生成问题
我用Selenium抓取IQAir网站的空气质量排名表格数据,目标是得到一个包含所有数值的一维数组,但当前代码逻辑有问题,无法实现需求。
原始代码
'use strict' const { helper, browserstackBase } = require('@core/IQAir') const webdriver = require('selenium-webdriver') const { initializeBrowser } = require('@core/IQAir/Automation-Library/library') class USaqMajorCityRankingTable extends browserstackBase { async execute(driver) { await driver.get('www.iqair.com/us/world-air-quality') await driver.sleep(2000) await initializeBrowser(driver) await driver.sleep(2000) const aqiData = await driver.findElements(webdriver.By.xpath("//table[@class = 'ranking__table ng-star-inserted']//td/p")); await helper.sleep(2000); await helper.sleep(2000); for (const aqi of aqiData){ await helper.sleep(2000); const a = await aqi.getText() const promise1= Promise.resolve(a) promise1.then((value) => { }); } } } module.exports = new USaqMajorCityRankingTable().runTest()
尝试修改的代码(未完成)
for (const aqi of aqiData){ const a = await aqi.getText() const promise1= Promise.resolve(a) promise1.then((value) => { const flattened = [].concat(...value); console.log (flattened)
遇到的问题
尝试通过[0][0]或[0][1]访问数组元素时,出现报错:
"cannot read properties of undefined (reading '0')"
疑似得到的是多维数组,无法正常访问单个元素。
解决方案
问题出在异步逻辑处理不当,以及错误的数组扁平化尝试:
getText()返回的是字符串而非数组,用concat(...value)会把字符串拆成单个字符的数组,反而导致混乱。- 循环中用
then()处理Promise会导致变量作用域问题,无法正确收集所有数据。
修改思路:
- 初始化一个空数组用于存储所有数据
- 用
for...of循环遍历元素,直接await getText()获取文本并推入数组 - 避免不必要的
Promise.resolve()和then()嵌套,利用async函数特性简化异步流程
修正后的代码
'use strict' const { helper, browserstackBase } = require('@core/IQAir') const webdriver = require('selenium-webdriver') const { initializeBrowser } = require('@core/IQAir/Automation-Library/library') class USaqMajorCityRankingTable extends browserstackBase { async execute(driver) { await driver.get('www.iqair.com/us/world-air-quality') await driver.sleep(2000) await initializeBrowser(driver) await driver.sleep(2000) const aqiData = await driver.findElements(webdriver.By.xpath("//table[@class = 'ranking__table ng-star-inserted']//td/p")); await helper.sleep(2000); // 初始化存储数据的一维数组 const fullAqiArray = []; // 遍历元素,收集所有文本值 for (const aqi of aqiData){ await helper.sleep(2000); const text = await aqi.getText(); // 去除文本前后空白后推入数组,如需数值可转换类型 fullAqiArray.push(text.trim()); } // 此时fullAqiArray就是包含所有数值的一维数组 console.log(fullAqiArray); return fullAqiArray; } } module.exports = new USaqMajorCityRankingTable().runTest()
额外优化建议
- 尽量减少固定时长的
sleep(),改用WebDriverWait等待元素加载,提升代码稳定性:const { until } = require('selenium-webdriver'); // 替换固定sleep为等待表格加载 await driver.wait(until.elementLocated(webdriver.By.xpath("//table[@class = 'ranking__table ng-star-inserted']")), 10000); - 如果表格数据是纯数值,可在推入数组前用
parseInt(text.trim())或parseFloat(text.trim())转换为数值类型,方便后续计算。
内容的提问来源于stack exchange,提问作者Beginner
相关产品推荐
相关产品推荐

