我正在尝试在循环中运行Selenium脚本来填充数据库。我有一个具有57个位置的对象数组,我需要遍历每个对象。
如何在保持异步的循环中完成它?我基本上想遍历每个商店,检查状态并保存到数据库。现在的问题是,当我在循环中运行它时,它在同步循环中运行异步代码,因此这是一个问题,因为它不等待一个任务完成而又启动另一个任务。
这是我数组的一部分
在代码中表示为商店
module.exports = [{ id: '1031', store: 'CANNES - LA BOCCA' },
{ id: '1009', store: 'ST ANDRÉ-LES-VERGERS' },
{ id: '1046', store: 'MARSEILLE ST MENET' },
{ id: '1071', store: 'MARIGNANE' },
{ id: '1020', store: 'IFS' },
{ id: '1032', store: 'CORMEILLES-EN-PARISIS' },
{ id: '1044', store: 'CERGY' },
{ id: '1055', store: 'HERBLAY' }];
这是我的代码
const chromeOptions = new chrome.Options().addArguments('disable-infobars', 'headless');
const chromeDesktop = {
prefs: {
profile: {
default_content_settings: {
images: 2,
},
managed_default_content_settings: {
images: 2,
},
},
},
};
const driver = new webdriver.Builder()
.withCapabilities(chromeDesktop)
.forBrowser('chrome')
.setChromeOptions(chromeOptions)
.build();
for (let index = 0; index < Stores.length; index++) {
(async function getStores(index) {
setTimeout(async () => {
try {
await driver.get('https://www.chronodrive.com');
await driver.manage().addCookie({
name: 'chronoShop',
value: `"shopId=${Stores[index].id}"`,
});
await driver.get('https://www.chronodrive.com');
await driver.wait(webdriver.until.elementLocated(webdriver.By.id('layer-overlay')), 4000);
await driver.executeScript('document.querySelector(\'#layer-overlay\').style.display = \'none\'');
await driver.executeScript('document.querySelector(\'#layer-wrapper\').style.visibility = \'hidden\'');
const text = await driver.findElement(webdriver.By.className('dispo--empty')).getText();
if (text.length > 30) {
const objA = {
store: Stores[index].store,
dispo: text,
id: Stores[index].id,
lastChecked: new Date(),
};
await Store.create(objA);
console.log(text);
} else {
const objB = {
store: Stores[index].store,
dispo: `*** Pas de disponibilité dans magasin de ${Stores[index].store} ***`,
id: Stores[index].id,
lastChecked: new Date(),
};
await Store.create(objB);
console.log(`*** Pas de disponibilité dans magasin de ${Stores[index].store} ***`);
}
} finally {
await driver.quit()
}
}, 1000 * index);
}(index));
}
我使用了临时解决方案设置超时功能,但这并不是真正的解决方案,因为有很多因素会影响该功能。
我读到可以以某种方式使用map函数和Promise.all(),但是我该怎么做呢?我是否对每行等待代码执行Promise.all()?这似乎效率不高,而且写起来很麻烦。
谢谢
最佳答案
const chromeOptions = new chrome.Options().addArguments("disable-infobars", "headless");
const chromeDesktop = {
prefs: {
profile: {
default_content_settings: {
images: 2
},
managed_default_content_settings: {
images: 2
}
}
}
};
const driver = new webdriver.Builder()
.withCapabilities(chromeDesktop)
.forBrowser("chrome")
.setChromeOptions(chromeOptions)
.build();
async function getStores(index) {
try {
await driver.get("https://www.chronodrive.com");
await driver.manage().addCookie({
name: "chronoShop",
value: `"shopId=${Stores[index].id}"`
});
await driver.get("https://www.chronodrive.com");
await driver.wait(webdriver.until.elementLocated(webdriver.By.id("layer-overlay")), 4000);
await driver.executeScript("document.querySelector('#layer-overlay').style.display = 'none'");
await driver.executeScript("document.querySelector('#layer-wrapper').style.visibility = 'hidden'");
const text = await driver.findElement(webdriver.By.className("dispo--empty")).getText();
if (text.length > 30) {
const objA = {
store: Stores[index].store,
dispo: text,
id: Stores[index].id,
lastChecked: new Date()
};
await Store.create(objA);
console.log(text);
} else {
const objB = {
store: Stores[index].store,
dispo: `*** Pas de disponibilité dans magasin de ${Stores[index].store} ***`,
id: Stores[index].id,
lastChecked: new Date()
};
await Store.create(objB);
console.log(`*** Pas de disponibilité dans magasin de ${Stores[index].store} ***`);
}
} finally {
await driver.quit();
}
}
(async() => {
for (let index = 0; index < Stores.length; index++) {
await getStores(index);
}
})();
关于javascript - 使用数组中的数据在循环中运行selenium函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60818966/