我的数据包含一个包含错误重复步骤的字符串列表。这些通常编码为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?我应该使用不同的包吗?
答案 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"
因为它会返回一个字符向量与列表。