当一些可能不是html时,如何使用rvest来解析html片段?

时间:2016-11-16 00:43:23

标签: r rvest

我的数据包含一个包含错误重复步骤的字符串列表。这些通常编码为html,但有时只是原始文本,偶尔是空的(NA)。我需要文本sans html。我试图用rvest来完成这个,但我遇到了问题。

我有这个函数,它将解析一行html并返回一个字符串:

library(rvest)
tf <- function(frag) {read_html(frag) %>% html_nodes("p") %>% html_text() %>% paste0(collapse = " ")}

这适用于正确的html:

foo <- c("<p>captain <p>tightpants", "<p>malcolm <p>reynolds")
lapply(foo, tf)

按预期工作。我收到了两根琴弦。

如果我有NA,它会尝试加载一个名为&#34; NA&#34;的文件:

foo <- c("<p>captain <p>tightpants", "<p>malcolm <p>reynolds", NA)
lapply(foo, tf)

同样,如果我的字符串不是html,它也会尝试加载文件:

foo <- c("<p>captain <p>tightpants", "<p>malcolm <p>reynolds", "something else")
lapply(foo, tf)

有没有办法让rvest总是假设字符串是html?我应该使用不同的包吗?

1 个答案:

答案 0 :(得分:2)

也许首先通过htmltidy::tidy_html()传递向量元素,这样你总是拥有HTML并使用更自由的XPath选择器来获取所有文本(并在返回之前清理它):

library(rvest)
library(htmltidy)

tf <- function(frag) {

  tidy_html(frag) %>%   
    read_html() %>% 
    html_nodes(xpath="//*[not(self::script)]/text()") %>% 
    html_text() %>% 
    paste0(collapse = " ") %>% 
    gsub("\\n", "", .) %>% 
    gsub("\ +", " ", .) %>% 
    trimws()

}

foo <- c("<p>captain <p>tightpants", "<p>malcolm <p>reynolds", "something else")
lapply(foo, tf)
## [[1]]
## [1] "captain tightpants"
## 
## [[2]]
## [1] "malcolm reynolds"
## 
## [[3]]
## [1] "something else"

如果您确定文字是&#34;清洁&#34; (即没有<script>标签)然后您可以制作选择器"//*/text()"

虽然,我也可以建议:

library(purrr)

map_chr(foo, tf)
## [1] "captain tightpants" "malcolm reynolds"   "something else"

因为它会返回一个字符向量与列表。