【问题标题】:Cannot save - load xml_document generated from rvest in R无法保存 - 加载从 R 中的 rvest 生成的 xml_document
【发布时间】:2016-10-08 19:00:22
【问题描述】:

read_html 函数会生成一个 xml_document,我想保存并稍后加载它来解析它。

问题是加载xml_document后里面没有html。

library(rvest)
library(magrittr)
doc <- read_html("http://www.example.com/")
doc %>% html_node("h1") %>% html_text

我得到:[1] "Example Domain"

但是当我首先保存 xml_document doc 对象并再次加载它时,似乎一切都已清除。

save(doc, file=paste0(getwd(), "/example.RData"))
rm(doc)

load(file=paste0(getwd(), "/example.RData"))
doc %>% html_node("h1") %>% html_text

我得到:Error: No matches

或者当我运行 doc 时,我得到:{xml_document} 一个空的 xml_document。

同样的情况是,当我运行doc 时,在加载它之后,我收到一条消息说 RStudio 已停止工作。

我在两台不同的windows机器上试过了,都遇到了同样的问题。

sessionInfo()

R version 3.3.0 (2016-05-03)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

locale:
[1] LC_COLLATE=English_United Kingdom.1252  LC_CTYPE=English_United Kingdom.1252   
[3] LC_MONETARY=English_United Kingdom.1252 LC_NUMERIC=C                           
[5] LC_TIME=English_United Kingdom.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] magrittr_1.5     rvest_0.3.1.9000 xml2_0.1.2      

loaded via a namespace (and not attached):
[1] httr_1.1.0  R6_2.1.2    tools_3.3.0 Rcpp_0.12.5

【问题讨论】:

标签: r xml rvest


【解决方案1】:

我找到了一种解决方法,虽然效率不高,但确实可以。

逻辑是将xml_document保存为字符串,然后用read_html再次读入。

library(rvest)
library(magrittr)
doc <- read_html("http://www.example.com/")

# convert it to character
doc %<>% as("character")

save(doc, file=paste0(getwd(), "/example.RData"))
rm(doc)

load(file=paste0(getwd(), "/example.RData"))
doc %>% read_html %>% html_node("h1") %>% html_text

【讨论】:

    【解决方案2】:

    我写了一些 ad hoc 函数来完成这个任务。它们比上一个答案略好,因为它们适用于 rvest 对象的列表,并且它们使用 RDS 而不是 RData 文件。这允许您将对象命名为任何您想要的名称。

    write_rvest = function(x, path, ...) {
      #convert to character
      #is list?
      if (is.list(x)) {
        x %<>% map(as.character)
      } else {
        x %<>% as.character
      }
    
      #save
      write_rds(x, path = path, ...)
    }
    
    read_rvest = function(path) {
      #load from file
      x = read_rds(path)
    
      #read
      if (is.list(x)) {
        x %<>% map(read_html)
      } else {
        x %<>% read_html
      }
    
      x
    }
    

    平等测试有效,但身份测试失败。尽管如此,这些对象工作并且它们具有相同的字节大小,所以我不知道为什么标识失败。也许它对 RAM 位置很敏感。

    【讨论】:

    • 不错的包装函数。如果有另一种选择,我还没有关闭已接受的答案。谢谢
    • 让我们拭目以待,看看 rvest 开发者是否会回答。 :)
    • 同样的问题依然存在,很遗憾
    【解决方案3】:

    这里的包装函数与 Deleet 在基本 R 代码中的相同。

    library(rvest)
    
    write_rvest = function(x, file, ...) {
      #convert to character
      #is list?
      if (is.list(x)) {
        x = Map(as.character, x)
      } else {
        x = as.character(x)
      }
    
      #save
      saveRDS(x, file = file, ...)
    }
    
    read_rvest = function(file) {
      #load from file
      x = readRDS(file)
    
      #read
      if (is.list(x)) {
        x <- Map(read_html, x)
      } else {
        x <- read_html(x)
      }
    
      x
    }
    

    【讨论】:

    • 好像你无缘无故重复了x = Map(as.character, x) (?)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    相关资源
    最近更新 更多