2016-11-16 42 views
0

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

我有这个功能,这将解析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”文件:

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

XML库不太方便,但确实有一个asText参数可以解决这个问题。 rvest中有没有类似的东西? –

回答

1

也许通过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" 

如果你确定文本是“干净的”(即没有0​​标签),那么你可以使选择器"//*/text()"

虽然,可能我也建议:

library(purrr) 

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

由于它会返回一个特征向量VS列表。

+0

感谢您的建议!我会尝试一下。 –