如何将 read_html 的输出保存和读取为 RDS 文件?

use*_*745 7 r rvest xml2

可以像这样保存和读取对象

# Save as file
saveRDS(iris, "mydata.RDS")

# Read back in 
readRDS("mydata.RDS")
Run Code Online (Sandbox Code Playgroud)

但这似乎不适用于用 xml2::read_html()

例子

library(rvest)
someobject <- read_html("https://stackoverflow.com/")
saveRDS(someobject, "someobject.RDS")
Run Code Online (Sandbox Code Playgroud)

它创建了一个文件,但不像预期的那样

readRDS("someobject.RDS")
Error in doc_is_html(x$doc) : external pointer is not valid
Run Code Online (Sandbox Code Playgroud)

发生了什么以及保存 html 对象的最简单方法是什么,以便它可以用最少的代码/大惊小怪加载回来?

nei*_*fws 6

回答“发生了什么”:saveRDS正在尝试序列化正在保存的对象。这里,对象someobject是一个包含元素someobject$doc和的列表someobject$node。元素的类型是externalptr(外部指针),这意味着它们引用保存在内存中的 C 数据结构。当外部指针被序列化时,引用会丢失。因此错误“外部指针无效”。

您可以someobject使用序列化as.character()并将其传递给saveRDS

saveRDS(as.character(someobject), "someobject.RDS")
Run Code Online (Sandbox Code Playgroud)

然后使用readRDSand重新创建对象read_html

someobject <- read_html(readRDS("someobject.RDS"))
Run Code Online (Sandbox Code Playgroud)

write_html()正如其他人建议的那样,它更容易使用。

这个 Github 问题线程中的一些讨论。


Ron*_*hah 3

我们可以使用write_xmland read_htmlfromxml2

before <- read_html("https://stackoverflow.com/")
xml2::write_xml(before, "someobject1.xml")
after <- xml2::read_html("someobject1.xml")
Run Code Online (Sandbox Code Playgroud)

然而,identical回报FALSE

identical(before, after)
#[1] FALSE
Run Code Online (Sandbox Code Playgroud)

但对它们的查询似乎返回相同的结果

library(rvest)
before %>%  html_nodes("div")
after %>% html_nodes("div")
Run Code Online (Sandbox Code Playgroud)