Javascript 木偶演员:向下滚动推特时间线停止

Javascript 木偶演员:向下滚动推特时间线停止,javascript,node.js,twitter,web-scraping,puppeteer,Javascript,Node.js,Twitter,Web Scraping,Puppeteer,我在用Puppeter抓取用户时间线上的所有推特URL时遇到了麻烦 对于Puppeter,脚本应该在scrollToEnd函数中的while循环的每次迭代中向下滚动时间轴,直到到达底部。为了监控进度,我让脚本输出previousHeight变量的值,该变量是document.body的当前scrollheight,每次执行滚动之前都会进行计算 但是,一旦输出值变为285834,滚动就会停止。令人费解的是,脚本既没有跳出while循环,也没有page.waitForFunction方法抛出超时错误

我在用Puppeter抓取用户时间线上的所有推特URL时遇到了麻烦

对于Puppeter,脚本应该在
scrollToEnd
函数中的while循环的每次迭代中向下滚动时间轴,直到到达底部。为了监控进度,我让脚本输出
previousHeight
变量的值,该变量是
document.body的当前
scrollheight
,每次执行滚动之前都会进行计算

但是,一旦输出值变为285834,滚动就会停止。令人费解的是,脚本既没有跳出while循环,也没有
page.waitForFunction
方法抛出超时错误

我应该如何重写
scrollToEnd
函数或脚本的任何其他部分,以便函数正确结束

下面是我的代码片段。为了简洁起见,不相关的函数被省略了

const puppeteer = require('puppeteer');

var UserUrls = ['https://twitter.com/someuser'];

// more functions here

async function scrollToEnd(
    page,
    ScrollDelay = 1000
) {
    try {
        let previousHeight = 0;
        let notEnd = await page.waitForFunction(`document.body.scrollHeight > ${previousHeight}`);
        while (notEnd) {
            previousHeight = await page.evaluate('document.body.scrollHeight');
            await page.evaluate('window.scrollBy(0, document.body.scrollHeight)');
            await page.waitFor(ScrollDelay);

            notEnd = await page.waitForFunction(`document.body.scrollHeight > ${previousHeight}`);
            console.log(previousHeight)
        };
        return;
    } catch (e) {
        return;
    };
};

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    var tweetUrls = [];
    for (let UserUrl of UserUrls) {
        await page.goto(UserUrl);
        await page.evaluate((async () => {
            await scrollToEnd(page);
        })());
        await page.screenshot({ path: 'PageEnd.png' });
        tweetUrls = await getTweetUrls(page, extractItems, 100);
    };
    await browser.close();
    console.log(tweetUrls);
})();

你能试试这两种方法中的一种吗?此脚本尝试通过比较滚动高度(如您所做)或等待标记流结束的元素可见来滚动到底部。所有滚动逻辑都放在浏览器上下文中计算的函数中。这两个函数都返回整个页面中的tweet count,以将结果与时间线顶部声明的用户tweet count进行比较。另外,我已经将第一次进近的延迟时间改为3秒,因为有时1秒对于滚动高度的改变来说似乎太小了

“严格使用”;
const puppeter=require('puppeter');
(异步函数main(){
试一试{
const browser=wait puppeter.launch({headless:false});
const[page]=wait browser.pages();
等待页面。转到('https://twitter.com/GHchangelog');
const data1=wait page.evaluate(scrollToBottomByMaxHeight);
log(`Tweets:${data1}`);
等待页面。转到('https://twitter.com/GHchangelog');
const data2=等待页面评估(scrollToBottomByEndElement);
log(`Tweets:${data2}`);
//等待浏览器关闭();
}捕捉(错误){
控制台错误(err);
}
})();
异步函数scrollToBottomByMaxHeight(){
试一试{
设前一高度=0;
让currentHeight=document.scrollingElement.scrollHeight;
while(以前的高度<当前高度){
previousHeight=document.scrollingElement.scrollHeight;
滚动窗口(0,以前的高度);
等待新的承诺((resolve)=>{setTimeout(resolve,3000);});
currentHeight=document.scrollingElement.scrollHeight;
}
return document.querySelectorAll('a.js-permalink')。长度;
}捕捉(错误){
返回错误;
}
}
异步函数scrollToBottomByEndElement(){
试一试{
const endElement=document.querySelector('div.stream-end');
while(endElement.clientHeight==0){
scrollBy(0,document.scrollingElement.scrollHeight);
等待新的承诺((resolve)=>{setTimeout(resolve,1000);});
}
return document.querySelectorAll('a.js-permalink')。长度;
}捕捉(错误){
返回错误;
}
}

scrollToBottomByMaxHeight
函数返回40,而
scrollToBottomByEndElement
函数返回186。我认为后者是一种更可靠的方法,因为
clientHeight
应该保持在0,直到
div.stream-end
元素被加载,这是正确的吗?@我经常从这两种方法中得到186条信息,但第一种方法似乎更脆弱,因为它取决于网络的响应性(您可以尝试将延迟增加到10秒,以查看是否有变化)。因此,我认为,是的,第二种方法更可靠。@figment
div.stream-end
已在初始页面状态加载,它只是隐藏到流的末尾,直到流的
clientHeight
为0。