首页 > 解决方案 > puppeteer await page.$$('.className'),但我只得到该类的前 11 个元素,为什么?

问题描述

我用来抓取学生名单的代码:

let collection1 = await page.$$('div.layout-2DM8Md')
  console.log("Student Online:")
  for (let el of collection1) {
    let name = await el.$eval(('div.name-uJV0GL'), node => node.innerText.trim());
    console.log(name)
  }

标签: node.jspuppeteer

解决方案


这可能是因为其余元素的内容是使用 Javascript 框架(如 React 或 Vue)动态加载的。这意味着只有当这些元素进入浏览器的视口时才会加载它。

要解决此问题,您需要编写一个自动滚动页面的函数,以便这些元素可以进入视口,然后您必须等待该函数完成才能收集数据。

滚动功能:

const autoScroll = async(page) => {
    await page.evaluate(async () => {
        await new Promise((resolve, reject) => {
            var totalHeight = 0;
            var distance = 100;
            var timer = setInterval(() => {
                var scrollHeight = document.body.scrollHeight;
                window.scrollBy(0, distance);
                totalHeight += distance;

                if(totalHeight >= scrollHeight){
                    clearInterval(timer);
                    resolve();
                }
            }, 30);
        });
    });
}

然后在获取内容之后 page.goto()之前调用此函数page.content()。我还设置了视口宽度和高度,然后滚动速度更快:

await page.goto(url, {waitUntil: 'load'});
await page.setViewport({
    width: 1200,
    height: 800
});
await autoScroll(page); // The scroll function
const html = await page.content()

推荐阅读