【问题标题】:How to make promise to wait for all objects to be complete and then push to array?如何承诺等待所有对象完成然后推送到数组?
【发布时间】:2021-03-22 12:30:33
【问题描述】:

getURL() 函数从原始 URL 创建一个抓取的 URL 数组。 getSubURL() 然后循环遍历该数组并抓取所有这些页面的 URL。目前,此代码可以很好地输出到控制台,但我不知道如何等待我的数据解析,因此我可以将所有收集的数据推送到单个数组。目前,当我尝试返回站点然后推送到数组时,它只推送最后一个值。我相信这是一个 promise.all(map) 的情况,但我不知道如何正确地写一个而不会出错。理想情况下,我完成的抓取可以在另一个函数中调用。可以的话请看一下

const cheerio = require('cheerio');
const axios = require('axios');

let URL = 'https://toscrape.com';

const getURLS = async () => {
  try {
    const res = await axios.get(URL);
    const data = res.data;
    const $ = cheerio.load(data);

    const urlQueue = [];

    $("a[href^='http']").each((i, elem) => {
      const link = $(elem).attr('href');
      if (urlQueue.indexOf(link) === -1) {
        urlQueue.push(link);
      }
    });
    return urlQueue;
  } catch (err) {
    console.log(`Error fetching and parsing data: `, err);
  }
};

const getSubURLs = async () => {
  let urls = await getURLS();

  try {
    //loop through each url in array
    for (const url of urls) {
      //fetch all html from the current url
      const res = await axios.get(url);
      const data = res.data;
      const $ = cheerio.load(data);

      //create object and push that url into that object 
      let sites = {};
      sites.url = url;
      let links = [];
      //scrape all links and save in links array
      $("a[href^='/']").each((i, elem) => {
        const link = $(elem).attr('href');
        if (links.indexOf(link) === -1) {
          links.push(link);
        }
        //save scraped data in object
        sites.links = links;
      });
      // returns list of {url:'url', links:[link1,link2,link3]}
      console.log(sites);
    }
  } catch (err) {
    console.log(`Error fetching and parsing data: `, err);
  }
};

【问题讨论】:

    标签: javascript node.js arrays asynchronous web-scraping


    【解决方案1】:

    不要认为这是一个与 Promise 相关的问题。

    您需要将sites 收集到一个在循环外初始化的数组中。然后当getSubURLs() 解析时,它会解析到你的数组:

    const getSubURLs = async() => {
      let urls = await getURLS();
      let siteList = [];
      try {
        for (const url of urls) {
          //         :
          //         :
          //         :
          siteList.push(sites);
        }
      } catch (err) {
        console.log(`Error fetching and parsing data: `, err);
      }
      return siteList; // array of objects
    };
    
    getSubURLs().then(console.log);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-17
      • 2021-05-21
      • 1970-01-01
      • 2018-03-05
      相关资源
      最近更新 更多