首页 > 解决方案 > 在哪里调用 for 循环以遍历值数组

问题描述

我有一个用于抓取的 javascript 函数。我将它与 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); 
});

我的 URL 包含在变量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); 
  });
}

标签: javascriptloopsfor-loopweb-scrapingpuppeteer

解决方案


i被提升,并且scrape是异步的 - 在scrape await最开始的 s 之后,for循环将完成,因此i将变为listOfURLs.length + 1,这意味着listOfURLs[i]稍后访问将不起作用。

改为使用let,以便每次迭代都有一个单独的i.

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

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

但是这些类型的for循环非常丑陋,并且是此类问题的常见来源 - 您可以考虑forEach改为,它具有更好的抽象性,具有函数范围(可组合)并且不需要手动迭代,如果您可以发送请求平行:

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如果您想串行发出请求)


推荐阅读