puppeteer waitForSelector 当有多个具有相同类的元素并且可以看到多个元素时

Posted

技术标签:

【中文标题】puppeteer waitForSelector 当有多个具有相同类的元素并且可以看到多个元素时【英文标题】:puppeteer waitForSelector when there are multiple elements with same class and more than one can be visible 【发布时间】:2022-01-21 11:28:01 【问题描述】:

我想要完成的是保存所有扩展的 cmets 的完整文档。 不幸的是,有多个具有相同类的选择器,其中大多数是隐藏的,我相信 puppeteer 所做的是首先找到选择器并等待直到它可见,而这永远不会发生。

网址:https://www.discoverpermaculture.com/permaculture-masterclass-video-1

const puppeteer = require('puppeteer');
const isElementVisible = async (page, cssSelector) => 
let visible = true;
await page
    .waitForSelector(cssSelector,  visible: true, timeout: 2000 )
    .catch(() => 
         visible = false;
     );
if(visible)console.log('Selector '+cssSelector+'visible!');
return visible;
;

async function run () 
let browser = await puppeteer.launch(headless: true, defaultViewport: null, args: ['--window-size=1920,10000',],);
const page = await browser.newPage();
const fs = require('fs');
await page.goto('https://www.discoverpermaculture.com/permaculture-masterclass-video-1');
await page.waitForTimeout(4000)

const elementHandle = await page.waitForSelector('iframe');
const frame = await elementHandle.contentFrame();
//loading all the comments (works because there's only one 'a.load-more__button' element a time)
const selectorForLoadMoreButton = 'a.load-more__button';
let loadMoreVisible = await isElementVisible(frame, selectorForLoadMoreButton);
while (loadMoreVisible) 
    console.log('Loading comments');
    await frame
        .click(selectorForLoadMoreButton)
        .catch(() => );
    loadMoreVisible = await isElementVisible(frame, selectorForLoadMoreButton);

//expanding comments doesn't work because each comment have a.see-more but some are hidden
const selectorForSeeMoreButton = 'a.see-more';
let seeMoreVisible = await isElementVisible(frame, selectorForSeeMoreButton);
while (seeMoreVisible) 
    console.log('Expanding comments');
    await frame
        .click(selectorForSeeMoreButton)
        .catch(() => );
    seeMoreVisible = await isElementVisible(frame, selectorForSeeMoreButton);

const cdp = await page.target().createCDPSession();
const  data  = await cdp.send('Page.captureSnapshot',  format: 'mhtml' );
fs.writeFileSync('out.mhtml', data);
browser.close();

run();

任何想法如何处理?

【问题讨论】:

URL 当前在控制台中显示错误:ReferenceError: PAGE_IDENTIFIER is not defined 我得到的唯一错误是“(node:12283) UnhandledPromiseRejectionWarning: ReferenceError: output is not defined”,现在已修复(编辑原始代码) 您所说的“所有 cmets 都已展开的完整文档”是什么意思。是否要将每个 cmets 导出到 xls 文件? 没有。另存为 mhtml 将使所有 cmets 可见。对于长 cmets disqus 添加了一个可点击的“查看更多”元素。我想要实现的是遍历所有这些以使它们完全可见,然后保存页面。我想到了。必须选择所有没有“隐藏”类的“a.see-more”元素。像这样:'a.see-more:not(.hidden)'。 【参考方案1】:

事实证明,每条评论都有“a.see-more”元素,但如果不是很长,它也有“.hidden”类。必须更新这段代码以搜索所有 'a.see-more' 元素但没有 '.hidden' 类。

    const selectorForSeeMoreButton = 'a.see-more:not(.hidden)';
    let seeMoreVisible = await isElementVisible(frame, selectorForSeeMoreButton);
    while (seeMoreVisible) 
        console.log('Expanding comments');
        await frame
            .click(selectorForSeeMoreButton)
            .catch(() => );
        seeMoreVisible = await isElementVisible(frame, electorForSeeMoreButton);
    

【讨论】:

以上是关于puppeteer waitForSelector 当有多个具有相同类的元素并且可以看到多个元素时的主要内容,如果未能解决你的问题,请参考以下文章

使用 Puppeteer 时等待文本出现

puppeteer 触发点击按钮不起作用

TypeError:无法将 undefined 或 null 转换为对象 Puppeteer

如何使用元素标题的一部分在 Puppeteer 或 Playwright 中找到元素?

玩笑-ReferenceError:导入的函数未定义

搜索await page.waitForSelector(allResultsSelector);