【问题标题】:strip DOM elements in Puppeteer, without using CSS selectors?在 Puppeteer 中剥离 DOM 元素,而不使用 CSS 选择器?
【发布时间】:2021-01-08 00:29:40
【问题描述】:

我想从 Puppeteer 中的 DOM 中剥离一些元素和 cmets。这些项目没有我可以使用 CSS 选择的可识别 ID、类或属性。但是,它们可能由内部字符串标识,并且某些元素可能包装在人类可读的 cmets 中。到目前为止我的尝试:

  • 似乎不可能使用 CSS 选择器,因为它们只能使用 ID 或类:there is no CSS contains() selector。所以我尝试用 XPath 来做...
  • 可以使用 XPath 选择(并可能删除?)某些元素,但我是 Puppeteer 和 XPath 的新手。我在下面提供了我失败的尝试。
  • 我可能会改用正则表达式,但我不知道如何在解析 HTML 后从 DOM 中删除字符串。

有什么想法吗?谢谢。


因此,在下面的示例中,我想删除<!-- DELETE ME ... --> cmets 之间的元素,以及末尾的<!-- DELETE ME ... --> cmets:

    <html>
      <head>

        <!-- DELETE ME BEGIN -->
        <script>
          // delete me
          console.log('delete me')
        </script>
        <!-- DELETE ME END -->

        <title>Page Title</title>
      </head>

      <body>
        
        <!-- DELETE ME BEGIN -->
        <style>
          body {
            /* delete me */
            color: red;
          }
        </style>
        <script>
          // delete me
          console.log('delete me')
        </script>
        <!-- DELETE ME END-->

        <style>
          body {
            /* keep me  */
            color: green;
          }
        </style>

        <script>
          // keep me
          console.log("keep me")
        </script>
        <p>Keep me</p>
        <!-- keep me -->

      </body>
    </html>

    <!-- DELETE ME -->
    <!-- DELETE ME TOO -->

Puppeteer/XPath 代码(只是一个尝试,还没有做任何事情):

    const browser = await puppeteer.launch();
    
    const page = await browser.newPage();
    page.on("console", (log) => console[log._type](log._text));

    const html = await page.evaluate(() => {
      var evaluator = new XPathEvaluator();
      var result = evaluator.evaluate(
        "//script[contains(.,'delete me')]",
        document,
        null,
        XPathResult.ANY_TYPE
      );

      console.log(result);

      return document.documentElement.outerHTML;
    });

    await browser.close();

【问题讨论】:

    标签: javascript xpath css-selectors puppeteer


    【解决方案1】:

    您的xpath 看起来正确。 Puppeteer 提供page .$x (expression) 函数来运行xpath

    const browser = await puppeteer.launch();
    
    const page = await browser.newPage();
    await page.goto('https://storm-bald-meteorology.glitch.me');
    
    let xs = await page.$x("//script[contains(. ,'delete me')]");
    console.log(xs.length);
    for (let x of xs) {
      let txt = await page.evaluate(el => el.innerText, x);
      console.log(txt);
    }
    
    await browser.close();
    
    

    您可以将此代码复制/粘贴到puppeteer playground 中进行尝试。我还将您的html 放在glitch 上。

    【讨论】:

    • 感谢您查看@sam-r!你的代码比我的好。你也碰巧知道我可以如何删除 DOM 元素吗?
    • @aljabear,只需拨打el.remove() 而不是el.innerText
    • 谢谢,非常感谢! :)
    【解决方案2】:

    未来自己的注意事项,这是我编写的包含@sam-r 解决方案的完整代码,在这种情况下,剥离元素添加到呈现的Wayback Machine 条目:

       // remove elements by XPath
        [
          ...await page.$x("//script[contains(.,'__wm')]"),
          ...await page.$x("//script[contains(.,'archive.org')]"),
          ...await page.$x("//style[contains(.,'margin-top:0 !important;\n  padding-top:0 !important;\n  /*min-width:800px !important;*/')]"),
          ...await page.$x("//comment()[contains(.,'WAYBACK')]"),
          ...await page.$x("//comment()[contains(.,'Wayback')]"),
          ...await page.$x("//comment()[contains(.,'playback timings (ms)')]"),
        ].forEach(async xpath => await page.evaluate(el => el.remove(), xpath));
    
        // remove elements by CSS Selector
        await page.evaluate(async () => {
          [
            document.querySelector('link[href*="/_static/css/banner-styles.css"]'),
            document.querySelector('link[href*="/_static/css/iconochive.css"]'),
            ...document.querySelectorAll("#wm-ipp-base"), // wayback header
            ...document.querySelectorAll('script[src*="wombat.js"]'),
            ...document.querySelectorAll('script[src*="archive.org"]'),
            ...document.querySelectorAll('script[src*="playback.bundle.js"]'),
            ...document.querySelectorAll("#donato"), // wayback donation header
          ].forEach((element) => element.remove());
        });
    

    【讨论】:

      猜你喜欢
      • 2017-12-10
      • 2020-05-24
      • 1970-01-01
      • 1970-01-01
      • 2023-02-25
      • 1970-01-01
      • 2018-05-04
      • 2012-08-16
      • 2010-10-27
      相关资源
      最近更新 更多