R:rvest提取innerHTML

Posted

技术标签:

【中文标题】R:rvest提取innerHTML【英文标题】:R: rvest extracting innerHTML 【发布时间】:2015-07-19 16:46:24 【问题描述】:

在 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/>"

所需的功能通常在 xml2 包的 write_xml 函数中可用,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 或其他包?特别是我想避免写入硬盘。

【问题讨论】:

似乎在 github 上提交问题可能更有效率... 后续,这被添加为一个问题和eventually resolved。答案就是使用as.character 【参考方案1】:

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

关于你最后一个代码 sn-p,它想在将&lt;br&gt; 转换为换行符时从节点中提取&lt;br&gt; 分隔的文本,在当前未解决的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"

【讨论】:

【参考方案2】:

这是使用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"

【讨论】:

这错过了一个问题,不是获取节点的文本,而是能够获取包含换行符的文本

以上是关于R:rvest提取innerHTML的主要内容,如果未能解决你的问题,请参考以下文章

R语言爬虫:Rvest包函数介绍

如何使用 R 中的 rvest 通过以下方式从 Wikipedia 获取“类别”?

从R中的链接中提取标题

用rvest提取xml路径

使用rvest在页面中提取多个表

R - 如何使用 rvest 或 rcurl 点击网页