弹出表单可见,但 Puppeteer 中缺少 html 代码

2024-05-13

我目前正在尝试从网站获取一些信息(https://www.bauhaus.info/ https://www.bauhaus.info/) 并在 cookie 弹出表单中失败。

到目前为止,这是我的代码:

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://www.bauhaus.info');
    await sleep(5000);
    const html = await page.content();
    fs.writeFileSync("./page.html", html, "UTF-8");
    page.pdf({
        path: './bauhaus.pdf', 
        format: 'a4'
    });
});

function sleep(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

直到这一切都正常。但我无法接受 cookie 横幅,因为我在 puppeteer 中看不到此横幅的 html。但在 pdf 中我可以看到表格。

enter image description here My browser

enter image description here Puppeteer

为什么我在 html 代码中看不到这个弹出窗口? 奖励任务:有没有办法在不知道哪个js方法触发cookie表单出现的情况下用任何page.await替换sleep方法?


该元素位于影子根中。请访问我的回答Puppeteer 没有为带有影子根的页面提供准确的 HTML 代码 https://stackoverflow.com/questions/68525115/puppeteer-not-giving-accurate-html-code-for-page-with-shadow-roots/68540701#68540701有关 Shadow DOM 的更多信息。

此代码深入到影子根,等待按钮出现,然后单击它。或者,它等待元素被删除,然后截取屏幕截图。

const puppeteer = require("puppeteer"); // ^19.11.1

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  const url = "https://www.bauhaus.info/";
  await page.goto(url, {waitUntil: "domcontentloaded"});
  const el = await page.waitForSelector("#usercentrics-root");
  const sel = '[data-testid="uc-accept-all-button"]';
  await page.waitForFunction((el, sel) =>
    el.shadowRoot.querySelector(sel),
    {},
    el,
    sel,
  );
  await el.evaluate((el, sel) =>
    el.shadowRoot.querySelector(sel).click(),
    sel
  );

  // to prove it worked, wait for the popup
  // to disappear, then take a screenshot
  const root = await page.waitForSelector("#usercentrics-root");
  await page.waitForFunction((root, sel) =>
    !root.shadowRoot.querySelector(sel), {}, root, sel
  );
  await page.screenshot({path: "clicked.png"});
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

自原始帖子发布以来,Puppeteer 有一种更简单的方法来遍历影子 DOM,>>>:

// ...
  await page.goto(url, {waitUntil: "domcontentloaded"});
  const sel = '[data-testid="uc-accept-all-button"]';
  const btn = await page.waitForSelector(">>> " + sel);
  await btn.click();
// ...

跳出框框思考,如果您并不真正需要单击按钮,而只需要尽可能快速轻松地摆脱模式,则可以炸掉整个外部容器、影子根和所有内容:

// ...
  await page.goto(url, {waitUntil: "domcontentloaded"});
  const el = await page.waitForSelector("#usercentrics-root");
  await el.evaluate(el => el.remove());
// ...

这是一种被低估的技术:如果页面的一部分妨碍您并且与您的目标无关,请将其撕掉并忘记它!这与阻止不需要的资源的精神类似。您不必按预期使用该网站。

进一步突破框框:根据您在网站上真正要完成的任务,您通常可以使用本机不受信任的 DOM 方法来完成它,例如.click() inside evaluate块,不关心可见性。这意味着您可以完全忽略模式。

也可以看看:无法找到并单击条件条款按钮 https://stackoverflow.com/questions/74057130/cant-locate-and-click-on-a-terms-of-conditions-button/74057427#74057427它使用相同的#usercentrics-root.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

弹出表单可见,但 Puppeteer 中缺少 html 代码 的相关文章

随机推荐