我正在使用"puppeteer": "^19.11.1",:

我创建了这个功能,按下这个Page上的同意按钮:

enter image description here

这就是我的功能:

async function handleConsent(page, logger) {
    const consentButtonSelector =
        '#uc-center-container > div.sc-eBMEME.ixkACg > div > div > div > button.sc-dcJsrY.bSKKNx';


    try {
        // Wait for the iframe to load
        await page.waitForSelector("iframe", { timeout: 3000 });

        // Identify the iframe that contains the consent button
        const iframeElement = await page.$(
            'iframe[name="__tcfapiLocator"]'
        );
        if (iframeElement) {
            const iframeContent = await iframeElement.contentFrame();

            // Attempt to click the consent button within the iframe
            const consentButton = await iframeContent.$(consentButtonSelector);
            if (consentButton) {
                await iframeContent.click(consentButtonSelector);
                logger.info("Consent button clicked inside the iframe.");
            } else {
                logger.info("Consent button not found inside the iframe.");
            }
        } else {
            logger.info("Iframe with the consent message not found.");
        }

        await page.waitForTimeout(3000); // Wait for any potential redirects or updates after clicking
    } catch (error) {
        logger.error(`An error occurred while handling consent: ${error}`);
    }
}

我的问题是没有找到 Select 器,即使我试图 Select iframe.

有什么建议我做错了吗?

感谢您的回复!

推荐答案

iframe中未放置同意按钮.放在#shadow-root里面. 要访问它,你需要先获取它的主机,然后获取属性shadowRoot,只有这样你才能访问它.

影子主机 Select 器为#usercentrics-root

但是,consensus被呈现为unctc,所以在获得它的主机之后,accept按钮还不能呈现,所以你需要等待consensus按钮的存在,例如,通过在evaluate块中实现waitFor函数.

点击按钮后,最好等到同意影子主机被隐藏.

更多关于shadowDOM

    const url =
      "https://www.immowelt.at/suche/wien/wohnungen/kaufen?d=true&pma=500000&sd=DESC&sf=TIMESTAMP&sp=1";
    await page.goto(url);
    const shadowHost = await page.waitForSelector('#usercentrics-root');
    await shadowHost.evaluate(async el => {
      let waitFor = async (action, timeoutMs = 10000, pollIntervalMs = 500) => {
        let isTimeout = false;
        const timeoutId = setTimeout(() => {
          isTimeout = true;
        }, timeoutMs);
        let result;
        while (!isTimeout && !result) {
          result = await action();
          await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
        }

        clearTimeout(timeoutId);
        if (isTimeout) {
          throw new Error('Timeout exceeded!');
        } else {
          return result;
        }
      };
      const accept = await waitFor(() => el.shadowRoot!.querySelector('[data-testid=uc-accept-all-button]'));
      accept.click();
    });
    await page.waitForSelector('#usercentrics-root', {hidden: true});

Javascript相关问答推荐

React对话框模式在用户单击预期按钮之前出现

react 路由加载程序行为

React:未调用useState变量在调试器的事件处理程序中不可用

在贝塞尔曲线的直线上找不到交叉点:(使用@Pomax的bezier.js)

在页面上滚动 timeshift 动垂直滚动条

google docs boldText直到按行执行应用脚本错误

将字符串UTC Date转换为ngx—counting leftTime配置值的数字

引用在HTMLAttributes<;HTMLDivElement>;中不可用

setcallback是什么时候放到macrotask队列上的?

在forEach循环中获取目标而不是父对象的属性

如何在不影响隐式类型的情况下将类型分配给对象?

如何使用TypeScrip设置唯一属性?

如果没有页面重新加载Angular ,innerHTML属性绑定不会更新

MongoDB中的嵌套搜索

为什么在运行于<;img>;事件处理程序中的JavaScript中x和y是不可变的?

重新渲染过多(&Q).REACT限制渲染次数以防止无限循环.使用REACT下拉菜单时

为什么这个最小Angular 的Licial.dev设置不起作用?

在Press Reaction本机和EXPO av上播放单个文件

不允许在对象文本中注释掉的属性

带元素数组的Mongo聚合