如何从html节点中删除2-3个元素并刮掉其余元素?

时间:2015-12-21 21:15:52

标签: r rvest

准确地说,我有一个课程,比如 A ,我通过rvest中的html_nodes选择。现在 A 可以包含许多子类和许多html标记,例如链接 img 标记。我想放弃一些特定的课程和来自 A 的标签,同时抓取其余数据。我不知道其余数据的类。我知道我想要黑名单。

HTML(假设)。此标记<div class="messageContent">在文档中重复最多25次,内容不同,但结构相同。

<div class="messageContent">
<article>
<blockquote class="messageText SelectQuoteContainer ugc baseHtml">
<div class="bbCodeBlock bbCodeQuote" data-author="Generic">

<aside>
<div class="attribution type">Generic said:
<a href="goto/post?id=32554#post-32754" class="AttributionLink">&uarr;</a>
</div>
<blockquote class="quoteContainer"><div class="quote">I see what you did there.</div><div class="quoteExpand">Click to expand...</div></blockquote>
</aside>

</div><img src="styles/default/xenforo/clear.png" class="mceSmilieSprite      mceSmilie9" alt=":o" title="Eek!    :o"/> Really?
<aside>
<div class="attribution type">Generic said:
<a href="goto/post?id=32554#post-32754" class="AttributionLink">&uarr;</a>
</div>
<blockquote class="quoteContainer"><div class="quote">I see what you did there.</div><div class="quoteExpand">Click to expand...</div></blockquote>
</aside>

<div class="messageTextEndMarker">&nbsp;</div>
</blockquote>
</article>
</div>

所以,我正在抓取的页面包含多个这样的类。我做了

posts <- page %>%  html_nodes(".messageContent") 

这给了我一个25个html节点的列表,每个节点包含上述html内容的变体。

我想删除<aside>&amp;中的所有内容</aside>代码(可以在帖子中的多个位置发生),并通过html_text() %>% as.character()

捕获其余的html

我可以用rvest做这个吗?

测试@MirosławZalewski的解决方案。

test<- page %>% html_node(".messageContent") %>%
          html_nodes(xpath='//*[not(ancestor::aside or name()="aside")]/text()')

这返回了页面中不在旁边的所有元素。一点微调,让我:

page %>% html_nodes(xpath='(//div[@class="messageContent"])[1]//*[not(ancestor::aside or name()="aside")]/text()') %>% html_text() %>% as.character()

迭代了25个课程,这正是我所需要的。

1 个答案:

答案 0 :(得分:2)

使用XPath,您可以选择不是df1.merge(df2[['sameid', 'addthiscolumn']], left_on='id', right_on='sameid') 的所有节点或<aside>的后代:

<aside>

不幸的是,这也会匹配包含page %>% html_node(".messageContent") %>% html_nodes(xpath='//*[not(ancestor::aside or name()="aside")]') 的元素。如果您将其传递给<aside>,则无论如何都会返回html_text()文字内容。

这可以通过在查询中添加另一个条件来克服。这种情况的一个好的候选者是“所有文本节点”:

<aside>

实际上,page %>% html_node(".messageContent") %>% html_nodes(xpath='//*[not(ancestor::aside or name()="aside")]/text()') 将仅返回文本节点,这几乎可以让您完全跳过/text()调用。但由于许多文本节点都是可疑的(只包含空白字符)并且此函数内置了html_text(),因此无论如何都可以考虑调用它。

请注意,此解决方案还会跳过任何非文字内容,例如图片参考(可能包括表情)。您的原始提案也会这样做,但我不清楚您是否打算这样做。