在哪里调用for循环来迭代值数组

时间:2018-06-04 00:04:20

标签: javascript loops for-loop web-scraping puppeteer

我有一个javascript函数,我正在使用scrape.I我正在使用它与Puppeteer。如果我使用一个值,它可以工作,但如果我为它引入一个for循环来迭代一个值数组,它就会失败。我想知道引入for循环的正确位置是什么。

这是我的工作基本脚本:

const puppeteer = require('puppeteer');
var listOfURLs = [url1, url2,url3,url4,url5]
let scrape = async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(listOfURLs[0]);

  const result = await page.evaluate(() => {
    let title = document.querySelector('#innerLeft > div.dspPropertyTitle > h1').innerText;
    return {
      title
    }

  });

  browser.close();
  return result;
};
scrape().then((value) => {
  console.log(value); 
});

我的网址包含在变量listOfURLs中。如果我手动引用listOfURLs [0],如上例所示,它可以正常工作。现在我希望它循环遍历整个数组并以listOfURLs [i]的形式访问值,所以我尝试了这个并且它没有工作。我不知道出了什么问题。

const puppeteer = require('puppeteer');    
var listOfURLs = [url1, url2, url3, url4, url5]
for (i=0; i<=listOfURLs.length; i++) {
  let scrape = async () => {
    const browser = await puppeteer.launch({headless: true});
    const page = await browser.newPage();

    await page.goto(listOfURLs[i]);

    const result = await page.evaluate(() => {
      let title = document.querySelector('#innerLeft > div.dspPropertyTitle > h1').innerText;
      return {
        title
      }

    });

    browser.close();
    return result;
  };
  scrape().then((value) => {
    console.log(value); 
  });
}

2 个答案:

答案 0 :(得分:1)

i已被悬挂,scrape为异步 - 在scrape await s开头后,for循环将完成,因此i将变为listOfURLs.length + 1,这意味着访问listOfURLs[i]后来无法工作。

请改用let,以便每次迭代都有i的单独绑定。

您还应该测试i < listOfURLs.length,而不是i <= listOfURLs.length,因为i < listOfURLs[listOfURLs.length]将是未定义的:

for (let i=0; i < listOfURLs.length; i++) {

但是这些for循环非常丑陋并且是这类问题的常见来源 - 您可能会考虑使用forEach,它具有更好的抽象,具有功能范围(可组合)并且不会# 39;如果您可以并行发送请求,则需要手动迭代:

listOfURLs.forEach(async (url) => {
  const scrape = async () => {
    const browser = await puppeteer.launch({headless: true});
    const page = await browser.newPage();
    await page.goto(url);
    const result = await page.evaluate(() => {
      const title = document.querySelector('#innerLeft > div.dspPropertyTitle > h1').innerText;
      return { title };
    });
    browser.close();
    return result;
  };
  scrape().then((value) => {
    console.log(value); 
  });
});

(如果你想连续发出请求,那么使用数组方法的另一个选项是reduce

答案 1 :(得分:0)

您的问题可能源于您在for循环中进行异步调用的事实。在进入下一个结果之前,您需要一个结果,并且由于它是异步的,因此您的代码不会等待响应并继续到数组中的下一个URL。