如何将 read_html 的输出保存和读取为 RDS 文件?
How to save and read output of read_html as an RDS file?
可以像这样保存和读取对象
# Save as file
saveRDS(iris, "mydata.RDS")
# Read back in
readRDS("mydata.RDS")
但这似乎不适用于使用 xml2::read_html()
制作的对象
例子
library(rvest)
someobject <- read_html("https://whosebug.com/")
saveRDS(someobject, "someobject.RDS")
创建了一个文件,但不是预期的那样
即
readRDS("someobject.RDS")
Error in doc_is_html(x$doc) : external pointer is not valid
这是怎么回事?保存 html 对象以便可以用最少的 code/fuss 将其加载回的最简单方法是什么?
在保存前使用toString()
将xml_document
class转换为character
,像这样
library(rvest)
someobject <- read_html("https://whosebug.com/")
someobject %>% toString %>% saveRDS(., "someobject.RDS")
newobject <- readRDS("someobject.RDS") %>% read_html
请注意,这些对象并不完全相同(我不确定为什么)。
identical(someobject, newobject)
# [1] FALSE
我们可以使用 xml2
包中的 write_xml
和 read_html
before <- read_html("https://whosebug.com/")
xml2::write_xml(before, "someobject1.xml")
after <- xml2::read_html("someobject1.xml")
然而,identical
returns FALSE
identical(before, after)
#[1] FALSE
但对它们的查询似乎 return 相同的结果
library(rvest)
before %>% html_nodes("div")
after %>% html_nodes("div")
回答"what's going on":saveRDS
正在尝试序列化正在保存的对象。这里,对象 someobject
是一个包含元素 someobject$doc
和 someobject$node
的列表。元素的类型是 externalptr
(外部指针),这意味着它们引用保存在内存中的 C 数据结构。当外部指针被序列化时,引用就会丢失。因此错误 "external pointer is not valid".
您可以使用 as.character()
序列化 someobject
并将其传递给 saveRDS
:
saveRDS(as.character(someobject), "someobject.RDS")
然后使用 readRDS
和 read_html
重新创建对象:
someobject <- read_html(readRDS("someobject.RDS"))
但是像其他人建议的那样使用 write_html()
更容易。
据我所知,使用 XML
和 RDS
文件的方法似乎相差相同的字符数。我做了一个比较,原始版本和加载版本之间的差异似乎在正文节点中。
url <- "https://whosebug.com/"
html <- read_match(url)
html_node(html, "body") %>% html_text() %>% unlist() -> OBT
nchar(OBT)
28879
xml2::write_xml(html, "someobject1.xml")
html_node(html, "body") %>% html_text() %>% unlist() -> BT1
nchar(BT1)
28893
html %>% toString %>% saveRDS(., "someobject.RDS")
after2 <- readRDS("someobject.RDS") %>% read_html
html_node(html, "body") %>% html_text() %>% unlist()-> BT2
nchar(BT2)
28893
这说明加载的两个对象的字符数相同。
如果我们从所有文本对象中删除一个“\n”字符,数字应该相同。
BT1 %>% str_remove_all(.,"\n") %>% nchar(.)
27733
BT2 %>% str_remove_all(.,"\n") %>% nchar(.)
27733
OBT %>% str_remove_all(.,"\n") %>% nchar(.)
27733
可以像这样保存和读取对象
# Save as file
saveRDS(iris, "mydata.RDS")
# Read back in
readRDS("mydata.RDS")
但这似乎不适用于使用 xml2::read_html()
例子
library(rvest)
someobject <- read_html("https://whosebug.com/")
saveRDS(someobject, "someobject.RDS")
创建了一个文件,但不是预期的那样 即
readRDS("someobject.RDS")
Error in doc_is_html(x$doc) : external pointer is not valid
这是怎么回事?保存 html 对象以便可以用最少的 code/fuss 将其加载回的最简单方法是什么?
在保存前使用toString()
将xml_document
class转换为character
,像这样
library(rvest)
someobject <- read_html("https://whosebug.com/")
someobject %>% toString %>% saveRDS(., "someobject.RDS")
newobject <- readRDS("someobject.RDS") %>% read_html
请注意,这些对象并不完全相同(我不确定为什么)。
identical(someobject, newobject)
# [1] FALSE
我们可以使用 xml2
包中的 write_xml
和 read_html
before <- read_html("https://whosebug.com/")
xml2::write_xml(before, "someobject1.xml")
after <- xml2::read_html("someobject1.xml")
然而,identical
returns FALSE
identical(before, after)
#[1] FALSE
但对它们的查询似乎 return 相同的结果
library(rvest)
before %>% html_nodes("div")
after %>% html_nodes("div")
回答"what's going on":saveRDS
正在尝试序列化正在保存的对象。这里,对象 someobject
是一个包含元素 someobject$doc
和 someobject$node
的列表。元素的类型是 externalptr
(外部指针),这意味着它们引用保存在内存中的 C 数据结构。当外部指针被序列化时,引用就会丢失。因此错误 "external pointer is not valid".
您可以使用 as.character()
序列化 someobject
并将其传递给 saveRDS
:
saveRDS(as.character(someobject), "someobject.RDS")
然后使用 readRDS
和 read_html
重新创建对象:
someobject <- read_html(readRDS("someobject.RDS"))
但是像其他人建议的那样使用 write_html()
更容易。
据我所知,使用 XML
和 RDS
文件的方法似乎相差相同的字符数。我做了一个比较,原始版本和加载版本之间的差异似乎在正文节点中。
url <- "https://whosebug.com/"
html <- read_match(url)
html_node(html, "body") %>% html_text() %>% unlist() -> OBT
nchar(OBT)
28879
xml2::write_xml(html, "someobject1.xml")
html_node(html, "body") %>% html_text() %>% unlist() -> BT1
nchar(BT1)
28893
html %>% toString %>% saveRDS(., "someobject.RDS")
after2 <- readRDS("someobject.RDS") %>% read_html
html_node(html, "body") %>% html_text() %>% unlist()-> BT2
nchar(BT2)
28893
这说明加载的两个对象的字符数相同。 如果我们从所有文本对象中删除一个“\n”字符,数字应该相同。
BT1 %>% str_remove_all(.,"\n") %>% nchar(.)
27733
BT2 %>% str_remove_all(.,"\n") %>% nchar(.)
27733
OBT %>% str_remove_all(.,"\n") %>% nchar(.)
27733