我如何 return 来自不同范围的所有数据并接收它们?

How can I return all data from different scope and receive them?

我尝试使用 Node.JS + Cheerio + Axios 抓取网站,我已经得到了我需要的所有东西,但问题是我不知道如何 return 来自不同范围的数据到收到它(我只能收到url,不能收到另一个范围内的data)。

我唯一可以接收的数据是url,但是在另一个范围内的所有data,我很想不出如何与[=一起接收它15=]

我的模块是如何工作的,它抓取了多个 url,每个 url 的内部包含 title, description, subtitle 等内容,所以这就是我必须映射 2 次的原因。

这是我的代码:

我用来抓取的服务:

exports.getSlides = async () => {
    const { data } = await client.get("/")

    const $ = cheerio.load(data)
    return $(".MovieListTop .TPostMv")
        .toArray()
        .map((element) => {
            const listItem = $(element)

            const url = listItem.find("a").attr("href")

            axios(url).then((res) => {
                const new$ = cheerio.load(res.data)

                new$(".TpRwCont")
                    .toArray()
                    .map((element) => {
                        const item = new$(element)

                        const title = item.find(".Title").first().text().trim()
                        const subTitle = item.find(".SubTitle").first().text().trim()
                        const description = item.find(".Description").first().text().trim()
                        const time = item.find(".Time").first().text().trim()
                        const date = item.find(".Date").first().text().trim()
                        const view = item.find(".View").first().text().trim()

                        // console.log({ title, subTitle, description, time, date, view })
                        return { data: { title, subTitle, description, time, date, view } }
                    })
            })
            return { url }
        })
}

我用来接收数据的控制器:

const movieServices = require("../services/index")

exports.getSlides = async (req, res, next) => {
    const data = await movie.getSlides()
    try {
        res.json({
            message: "Success",
            data: data,
        })
    } catch (err) {
        next(err)
    }
}

我的期望:

{
  "message:": "Success",
  "data": [
    {
      "url": "url1",
      "data": {
        "title": "titleA",
        "subTitle": "subTitleA",
        ...key : value
      }
    },
    {
      "url": "url2",
      "data": {
        "title": "titleB",
        "subTitle": "subTitleB",
        ...key : value
      }
    },
    {
      "url": "url3",
      "data": {
        "title": "titleC",
        "subTitle": "subTitleC"
        ...key : value
      },
      more objects
    }
  ]
}

这是一个重新设计的版本,它使用 async/await 来序列化请求、组织数据和 return 承诺中的数据。然后调用者可以使用 await.then() 从 promise 中获取数据。

我不完全确定我是否理解您想要的结果,因为您在问题和评论中描述的内容与代码生成的内容不完全匹配。此代码获取 URL 的顶级数组,然后对于每个 URL,URL 具有的每个 newsElement 都有一个数据对象数组。因此,有一个对象数组,其中每个对象都有一个 url 和一个数据数组。数据是 url 页面中的一组 newsElement 对象,如下所示:

[
    {
      url: url1, 
      data: [
        {
          title: someTitle1, 
          subTitle: someSubTitle1, 
          description: someDescription1, 
          time: someTime1, 
          date: someDate1, 
          view: someView1
        },
        {
          title: someTitle2, 
          subTitle: someSubTitle2, 
          description: someDescription2, 
          time: someTime2, 
          date: someDate2, 
          view: someView2
        }
      ]
    },
    {
      url: url2, 
      data: [
        {
          title: someTitle3, 
          subTitle: someSubTitle3, 
          description: someDescription3, 
          time: someTime3, 
          date: someDate3, 
          view: someView3
        },
        {
          title: someTitle4, 
          subTitle: someSubTitle4, 
          description: someDescription4, 
          time: someTime4, 
          date: someDate4, 
          view: someView4
        }
      ]
   },
]

而且,这是代码:

exports.getSlides = async () => {
    const { data } = await client.get("/");
    const $ = cheerio.load(data);
    const elements = $(".MovieListTop .TPostMv").toArray();
    const results = [];
    for (let element of elements) {
        const listItem = $(element);
        const url = listItem.find("a").attr("href");
        // for each url, we collect an array of objects where
        // each object has title, subTitle, etc.. from a newsElement
        const urlData = [];
        const res = await axios(url);
        const new$ = cheerio.load(res.data);
        const newsElements = new$(".TpRwCont").toArray();
        for (let newsElement of newsElements) {
            const item = new$(newsElement);
            const title = item.find(".Title").first().text().trim()
            const subTitle = item.find(".SubTitle").first().text().trim()
            const description = item.find(".Description").first().text().trim()
            const time = item.find(".Time").first().text().trim()
            const date = item.find(".Date").first().text().trim()
            const view = item.find(".View").first().text().trim()

            // console.log({ title, subTitle, description, time, date, view })
            urlData.push({ title, subTitle, description, time, date, view });
        }
        results.push({ url, data: urlData });
    }
    return results;
}

如果您希望收集的数据略有不同,您应该能够修改此代码以更改其组织数据的方式。