如何仅从父HTML节点(子节点除外)提取文本?

时间:2016-08-31 06:25:35

标签: r xml xpath html-parsing rvest

我有一个代码:

<div class="activityBody postBody thing">
    <p>
        <a href="/forum/conversation/post/3904-22" rel="post" data-id="3904-22" class="mqPostRef">(22)</a>
        where?
    </p>
</div>

我正在使用此代码提取文本:

html_nodes(messageNode, xpath=".//p") %>% html_text() %>% paste0(collapse="\n")

得到结果:

"(22) where?"

但我只需要“p”文本,不包括子节点中可能位于“p”内的文本。我必须得到这个文字:

"where"

在获取文本时有没有办法排除子节点?

Mac OS 10.11.6(15G31),RSrudio版本0.99.903,R版本3.3.1(2016-06-21)

2 个答案:

答案 0 :(得分:2)

如果您确定所需的文字始终位于最后,您可以使用:

doc %>% html_nodes(xpath=".//p/text()[last()]") %>% xml_text(trim = TRUE)

或者,您可以使用以下选项来选择所有“非空”曲线

doc %>% html_nodes(xpath=".//p/text()[normalize-space()]") %>% xml_text(trim = TRUE)

有关normalize-space()的更多详情,请参阅https://developer.mozilla.org/en-US/docs/Web/XPath/Functions/normalize-space

第3个选项是直接通过以下方式使用xml2包:

doc %>% xml2::xml_find_chr(xpath="normalize-space(.//p/text())")

答案 1 :(得分:1)

这将抓取<p>个孩子的所有文字(这意味着它不会包含来自子节点的文字,这些子节点不是&#34;文本发射器&#34;:

library(xml2)
library(rvest)
library(purrr)

txt <- '<div class="activityBody postBody thing">
    <p>
        <a href="/forum/conversation/post/3904-22" rel="post" data-id="3904-22" class="mqPostRef">(22)</a>
        where?
    </p>
  <p>
    stays 
    <b>disappears</b>
    <a>disappears</a>
    <span>disappears</span>
    stays
  </p>
</div>'

doc <- read_xml(txt)

html_nodes(doc, xpath="//p") %>% 
  map_chr(~paste0(html_text(html_nodes(., xpath="./text()"), trim=TRUE), collapse=" "))
## [1] "where?"     "stays stays"

不幸的是,那个漂亮的&#34;有损&#34; (你丢失了<b><span>等等,但是这个或@ Floo0(也可能是有损)解决方案可能对你有用。

如果使用XML包,则可以实际编辑节点(即删除节点元素)。