【问题标题】:XPath to select and concatenate all text nodesXPath 选择并连接所有文本节点
【发布时间】:2018-06-12 16:33:09
【问题描述】:

我正在从一个看起来像这样的网站抓取数据:

<div class="content">
  <blockquote>
    <div>
      Do not select this.
    </div>
    How do I select only this…
    <br />
    and this…
    <br />
    and this in a single node?
  </blockquote>
</div>

假设像这样的 sn-p 在单个页面上出现 20 次,我想获取 &lt;blockquote&gt; 中的所有文本,但忽略子节点中的所有内容,例如内部 div

因此我使用:

html %>%
  html_nodes(xpath = "//*[@class='content']/blockquote/text()[normalize-space()]")

但是,这会将 How do I select only this…and this…and this in a single node? 分隔为 xml_nodeset 结构中的各个元素。

我应该怎么做才能基本上将所有这些文本节点连接成一个并返回相同的 20 个元素(或者如果我只有这个示例,则返回一个)?

【问题讨论】:

    标签: r xpath web-scraping rvest


    【解决方案1】:

    您可以尝试在 XPath 下连接所有子子字符串:

    "string-join(//*[@class='content']/blockquote/text()[normalize-space()], ' ')"
    

    输出是

    How do I select only this… and this… and this in a single node?
    

    【讨论】:

    • 谢谢!我不怀疑您在技术上是正确的,但不幸的是rvest 似乎不支持 XPath 2.0,因为它说:xmlXPathCompOpEval: function string-join not found。我也试图用concat() 来做这件事,但无济于事。
    • 如果您确定需要多少文本节点,可以使用concat(//*[@class='content']/blockquote/text()[normalize-space()][1], ' ', //*[@class='content']/blockquote/text()[normalize-space()][2], ' ', //*[@class='content']/blockquote/text()[normalize-space()][3]),但这不是一个好的选择...
    • 不幸的是,我没有,而且就像你说的那样,这似乎不是一个好的选择。我将在rvest 或下面使用的任何库中了解有关 XPath 2.0 状态的更多信息,并且可能会询问开发人员是否打算实现此功能。
    【解决方案2】:

    您可以使用 xml_remove() 函数使用 CSS 或 XPATH 删除您的节点。

    library(rvest)
    
    text <- '<div class="content">
      <blockquote>
        <div>
          Do not select this.
        </div>
        How do I select only this…
        <br />
        and this…
        <br />
        and this in a single node?
      </blockquote>
    </div>'
    
    myhtml <- read_html(text)
    
    #select the nodes you don't want to select
    do_not_select <- myhtml %>%
        html_nodes("blockquote>div") #using css
    
    #remove those nodes
    xml_remove(do_not_select)
    

    您可以删除空格并稍后\n

    #sample result
    myhtml %>%
        html_text()
    [1] "\n  \n    \n    How do I select only this…\n    \n    and this…\n    \n    and this in a single node?\n  \n"
    

    【讨论】:

    • 这很好用,非常感谢!我想看看这是否可以仅使用 rvest 中的 XPath 来完成,但我很可能会接受您的回答,因为似乎不支持 XPath 2.0。
    • 我对 XPATH 语法不是很熟悉,但只要您正确选择节点,它就可以正常工作。并且使用xml_remove() 将删除所有选定的节点。
    猜你喜欢
    • 2011-06-29
    • 2011-06-13
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 1970-01-01
    • 2018-03-15
    • 2011-05-30
    相关资源
    最近更新 更多