在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"
有没有更好的方法来处理现有的功能,例如: rvest
,xml2
,XML
或其他套餐?特别是我想避免写入硬盘。
答案 0 :(得分:0)
正如@ r2evans所说,as.character(doc)
是解决方案。
关于您最后一段代码片段,它希望在将<br>
转换为换行符时从节点中提取<br>
分隔的文本,但目前尚未解析的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"
答案 1 :(得分:0)
以下是使用rvest
0.3.5的解决方案:
doc <- xml2::read_html('<html><p class="pp">First Line<br />Second Line</p>')
nodes <- rvest::html_nodes(doc, css = '.pp')
# {xml_nodeset (1)}
# [1] <p class="pp">First Line<br>Second Line</p>
rvest::html_text(nodes)
# [1] "First LineSecond Line"