我有一个要抓取的网站,我需要抓取的是一个 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}`);
答案 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秒之间设置随机超时,这至少会给您的脚本加载页面所需的时间,请记住并非所有页面都是平等创建的,并且网络连接也是一个问题。