我正在尝试在循环中运行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/

10-11 21:24