我想在R中使用 rvest 抓取网页,我想从节点中提取等效的innerHTML,特别是在应用html_text之前将换行符更改为换行符。

所需功能的示例:

library(rvest)
doc <- read_html('<html><p class="pp">First Line<br />Second Line</p>')
innerHTML(doc, ".pp")

应产生以下输出:
[1] "<p class=\"pp\">First Line<br>Second Line</p>"

使用rvest 0.2可以通过来实现。toString.XMLNode
# run under rvest 0.2
library(XML)
html('<html><p class="pp">First Line<br />Second Line</p>') %>%
  html_node(".pp") %>%
  toString.XMLNode
[1] "<p class=\"pp\">First Line<br>Second Line</p>"

对于较新的rvest 0.2.0.900,此功能不再起作用。
# run under rvest 0.2.0.900
library(XML)
html_node(doc,".pp") %>%
  toString.XMLNode
[1] "{xml_node}\n<p>\n[1] <br/>"

所需功能通常在write_xml现在依赖的xml2包的 rvest 函数中可用-如果只有write_xml可以将其输出提供给变量,而不是坚持要写入文件。 (同样不接受textConnection)。

作为一种解决方法,我可以临时写入文件:
# extract innerHTML, workaround: write/read to/from temp file
html_innerHTML <- function(x, css, xpath) {
  file <- tempfile()
  html_node(x,css) %>% write_xml(file)
  txt <- readLines(file, warn=FALSE)
  unlink(file)
  txt
}
html_innerHTML(doc, ".pp")
[1] "<p class=\"pp\">First Line<br>Second Line</p>"

这样,我就可以例如将换行符转换为换行符:
html_innerHTML(doc, ".pp") %>%
  gsub("<br\\s*/?\\s*>","\n", .) %>%
  read_html %>%
  html_text
[1] "First Line\nSecond Line"

有没有更好的方法可以使用例如rvestxml2XML或其他软件包?特别要避免写入硬盘。

最佳答案

正如@ r2evans所指出的,as.character(doc)是解决方案。

关于您最后一个想要将<br>转换为换行符时将<br>分隔的文本提取到节点之外的文本的代码片段,当前 Unresolved rvest issue #175, comment #2中有一种解决方法:

此问题的简化版本:

doc <- read_html('<html><p class="pp">First Line<br />Second Line</p>')

# r2evan's solution:
as.character(rvest::html_node(doc, xpath="//p"))
##[1] "<p class=\"pp\">First Line<br>Second Line</p>"

# rentrop@github's solution, simplified:
innerHTML <- function(x, trim = FALSE, collapse = "\n"){
    paste(xml2::xml_find_all(x, ".//text()"), collapse = collapse)
}
innerHTML(doc)
## [1] "First Line\nSecond Line"

10-02 00:45