如何使用 NodeJS 和 Cheerio 迭代 div 以从网站中抓取文本?

问题描述 投票:0回答:1

我试图从网站的 5 个不同的 div 中抓取文本,但问题是我无法使用类名或 ID。我观察到这些 div 的共同点是,这 5 个不同 div 的文本都封装在一个 span 属性中,并且该属性仅在我需要从中抓取文本的地方使用。到目前为止,这是我的代码,但我被困在抓取的开始:

const fs = require("fs/promises"); 
const express = require ("express"); 
const cors = require("cors");
const _ = require("lodash"); //pick a random item from an array
const { v4: uuid } = require("uuid"); //object destructuring; uuid to generate unique id
const { sample } = require("lodash");
const cheerio = require("cheerio");
const axios = require("axios");

async function performScraping(){

const app = express();

app.use(express.json()); //support json
app.use(express.cors());

//Downloading the target web page
//by performing an HTTP GET request in Axios
const axiosResponse = await axios.request({
    method: "GET",
    url: "https://wsa-test.vercel.app/",
    headers: {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
    }
});

//parsing the HTML source of the target web page with Cheerio
const $ = cheerio.load(axiosResponse.data);

//initializing the data structures
//that will contain the scraped data

//scraping
const descriptions = document.getElementsByTagName("span");
for(desc of descriptions){
    
}


app.listen(3000, () => console.log("API Server is running..."));
}

所以,tldr,我真正想要的是使用 Cheerio 提取文章的标题和简短描述,两者都在 span 属性中。我还附上了 HTML 图像和原因中的跨度:HTML

我尝试使用不同的 DOM 元素,但没有成功。

javascript html node.js cheerio
1个回答
0
投票

您将无法通过直接请求静态 HTML 来获取该数据,因为您想要的数据是由 JS 异步加载的。始终在浏览器中检查

view-source:
或打印 HTML axios 为您提供的信息,以确保数据存在,而不是开发工具,后者显示页面加载后由 JS 加载的元素。

你可以使用 Puppeteer 来获取它:

const puppeteer = require("puppeteer"); // ^21.2.1

const url = "https://wsa-test.vercel.app/";

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  await page.goto(url, {waitUntil: "domcontentloaded"});
  const sel = '[class^="group"]';
  await page.waitForSelector(sel);
  const data = await page.$$eval(sel, els => 
    els.map(e => ({
      name: e.querySelector("div").textContent,
      desc: e.querySelector("div:nth-child(2)").textContent
    }))
  );
  console.log(data);
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());
© www.soinside.com 2019 - 2024. All rights reserved.