木偶无限滚动

时间:2019-08-26 11:34:08

标签: javascript node.js puppeteer

我有一个要抓取的网站,我需要抓取的是一个 div ,该ID的ID为 left_container_scroll ,其中包含多个 a标签 。该div上具有无限滚动,我无法使其正常运行。我正在尝试使该程序在该div中滚动。

我试图做这样的事情,但出现错误:评估失败:ReferenceError:未定义elem

htmlTag = '#left_container_scroll';

//I think I am doing something wrong here
let elem = await page.evaluate((htmlTag)=> {
    return document.querySelector(htmlTag);
})

previousHeight =  await page.evaluate("elem.scrollHeight");
await page.evaluate("window.scrollTo(0,elem.scrollHeight)");
await page.waitForFunction(`elem.scrollHeight > ${previousHeight}`);

3 个答案:

答案 0 :(得分:3)

其中一些JavaScript代码在浏览器中运行,某些在Node.js运行时内部运行,它们看不到彼此的变量。

例如,page.evaluate("elem.scrollheight")无法看到您在上面设置的elem变量,因为该变量位于Node.js运行时内部,并且代码elem.scrollheight正在内部运行。浏览器(之前与htmlTag相似的问题)。
要将值从Node.js传递到浏览器,通常需要向page.evaluate提供附加参数。

类似的事情可能会起作用(尚未测试滚动是否按预期工作,但至少Puppeteer运行了代码)

// returns a Puppeteer ElementHandle (not browser DOM element)
let elem = await page.$(htmlTag)
// passes the ElementHandle back to the browser code (Puppeteer converts it back to DOM element)
let previousHeight = await page.evaluate(e => e.scrollHeight, elem)
// again, pass ElementHandle
await page.evaluate(e => window.scrollTo(0, e.scrollHeight), elem)
// pass both ElementHandle and previousHeight to the browser side
await page.waitForFunction((e, ph) => e.scrollHeight > ph, {}, elem, previousHeight)   

答案 1 :(得分:1)

我上次爬网的时候做了一个很简单的解决方案,希望能帮到你!

let lastHeight = await page.evaluate('document.body.scrollHeight');

while (true) {
    await page.evaluate('window.scrollTo(0, document.body.scrollHeight)');
    await page.waitForTimeout(2000); // sleep a bit
    let newHeight = await page.evaluate('document.body.scrollHeight');
    if (newHeight === lastHeight) {
        break;
    }
    lastHeight = newHeight;
}

答案 2 :(得分:0)

我会考虑要拖动的元素,假设使用无限滚动,您正在寻找更多的元素。我将为要拉取的元素设置一个基数计数器,然后有一个循环,用于检查先前的元素计数是否等于新的元素计数,这样,您可以中断循环,然后提取所需的数据。就我而言,我将为element_limit设置另一个检查,例如100,无论循环是否完成,都会中断循环。您可能还需要考虑在1-5秒之间设置随机超时,这至少会给您的脚本加载页面所需的时间,请记住并非所有页面都是平等创建的,并且网络连接也是一个问题。