【问题标题】:How can I get HTML elements between two independent tags如何在两个独立标签之间获取 HTML 元素
【发布时间】:2020-05-08 15:27:33
【问题描述】:

我正在使用 puppeteer。我有一种情况,我需要在两个不属于父子关系的标签之间获取内容。

<h1>neverchangeA<h1>
<span>abc<span>
<span>abc2<span>
<h1>neverchangeB<h1>

预期元素

<span>abc<span>
<span>abc2<span>

简单来说,我需要类似这样的正则表达式:

regex.matchBetween(<h1>neverchangeA<h1>,<h1>neverchangeB<h1>)

【问题讨论】:

  • 我不确定,我需要这两个 h1 元素之间的任何元素,比如正则表达式
  • 你打算如何处理标签之间的内容?您只需要原始 HTML 还是需要 puppeteer 处理对元素的引用?
  • 原始 html 内容
  • 您的示例 html 格式错误,因为它缺少 /s。

标签: javascript node.js web-scraping puppeteer


【解决方案1】:

Getting the sibling of an elementHandle in Puppeteer 解释了如何使用 puppeteer 获取元素的前一个兄弟。有一个类似的函数可以获取元素的下一个兄弟。您可以通过编写一个从第一个 &lt;h1&gt; 元素开始然后重复获取下一个同级元素直到到达第二个 &lt;h1&gt; 元素的循环来将此应用于您的情况。

【讨论】:

    【解决方案2】:

    您可以使用 JS 和评估方法来做到这一点。

    https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#pageevaluatepagefunction-args

    此示例将所需元素的 HTML 作为字符串返回。

    const result = await page.evaluate(() => {
      const h1s = [...document.querySelectorAll('h1')]
      const neverChangeA = h1s.find(elem => elem.innerText === "neverchangeA")
      if(neverChangeA){
        const siblings = [...neverChangeA.parentNode.children]
        const indexOfFirstH1 = siblings.findIndex(elem => elem.innerText === "neverchangeA")
        const indexOfSecondH1 =  siblings.findIndex(elem => elem.innerText === "neverchangeB")
        const betweenELems = siblings.slice(indexOfFirstH1 + 1, indexOfSecondH1)
        const htmlOfElems = betweenELems.map(elem => elem.outerHTML)
        const result = htmlOfElems.join('')
        return Promise.resolve(result)
      }
      else {
        return Promise.resolve(null)
     }
    })
    console.log(result)
    

    【讨论】:

      【解决方案3】:

      使用 XPath 的解决方案

      这是XPath 的一个很好的用例。以下查询查找span 元素,这些元素前面有一个h1 标记,内容为neverchangeA,后面有一个h1 标记,内容为neverchangeB

      //span[preceding::h1="neverchangeA" and following::h1="neverchangeB"]
      

      要在 puppeteer 中使用 XPath 表达式,请使用 page.$x

      代码示例

      const spans = await page.$x('//span[preceding::h1="neverchangeA" and following::h1="neverchangeB"]');
      

      【讨论】:

        【解决方案4】:

        您应该使用正则表达式。这:&lt;h1&gt;.*&lt;h1&gt; 将选择 h1 标签以及标签之间的任何内容。一种方法是从文本中删除 this 的结果,您将获得所需的结果。

        【讨论】:

        • 我们是内置在 puppeteer 还是纯 JavaScript 正则表达式中
        • 假设您使用捕获组修改正则表达式,该组将包含比 OP 想要的更多的字符。
        猜你喜欢
        • 1970-01-01
        • 2021-03-31
        • 1970-01-01
        • 2019-02-01
        • 2017-09-21
        • 2017-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多