【问题标题】:how to write a dataframe containing html data to disk?如何将包含 html 数据的数据框写入磁盘?
【发布时间】:2020-07-12 02:54:22
【问题描述】:

考虑这个简单的例子

library(rvest)
library(tidyverse)
library(dplyr)
library(lubridate)
library(tibble)

mytib <- tibble(mylink = c('https://en.wikipedia.org/wiki/List_of_software_bugs',
                           'https://en.wikipedia.org/wiki/Software_bug'))


mytib <- mytib %>% mutate(html.data = map(mylink, ~read_html(.x)))

> mytib
# A tibble: 2 x 2
  mylink                                              html.data 
  <chr>                                               <list>    
1 https://en.wikipedia.org/wiki/List_of_software_bugs <xml_dcmn>
2 https://en.wikipedia.org/wiki/Software_bug          <xml_dcmn>

> mytib$html.data[1]
[[1]]
{html_document}
<html class="client-nojs" lang="en" dir="ltr">
[1] <head>\n<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\n<meta charset="UTF-8">\n<title> ...
[2] <body class="mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject mw-editable page-List_of_software_b ...

如您所见,我的tibble 正确包含存储在mylink 列中的两个不同维基百科页面的html 代码。问题是我无法将这个辛苦的抓取存储到磁盘上。一个简单的read_csv 会失败

> mytib %>% write_csv('mydata.csv')
Error in stream_delim_(df, path, ..., bom = bom, quote_escape = quote_escape) : 
  Don't know how to handle vector of type list.

写入rds 时将无法正常工作

mytib %>% write_rds('mydata.rds')
test <- read_rds('mydata.rds')
test$html.data[1]

> test$html.data[1]
[[1]]
Error in doc_type(x) : external pointer is not valid

我该怎么办?我应该以哪种格式存储我的数据? 谢谢!

【问题讨论】:

    标签: html r web-scraping purrr


    【解决方案1】:

    已经讨论了这个原因here
    作为一种解决方法,您可以将 xmlDoc 转换为字符串以保存它:

    mytib <- mytib %>% mutate(html.data = map(mylink, ~toString(read_html(.x))))
    mytib %>% write_rds('mydata.rds')
    test <- read_rds('mydata.rds')
    test$html.data[[1]]
    [1] "<!DOCTYPE html>\n<html class=\"client-nojs\" lang=\"en\" dir=\"ltr\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<meta charset=\"UTF-8\">\n<title>List of software bugs - Wikipedia</title>\n
    

    然后您可以重新创建一个 xml 文档:

    test %>% mutate(xmlDoc = map(html.data,~read_html(.x))
    # A tibble: 2 x 3
      mylink                                              html.data xmlDoc    
      <chr>                                               <list>    <list>    
    1 https://en.wikipedia.org/wiki/List_of_software_bugs <chr [1]> <xml_dcmn>
    2 https://en.wikipedia.org/wiki/Software_bug          <chr [1]> <xml_dcmn>
    

    【讨论】:

      【解决方案2】:

      您真的需要将整个 html 存储在 csv 中吗? html 本身没有用,您可能希望提取所需的相关部分并将其存储在列中。比如这里提取标题。

      library(dplyr)     
      library(rvest)
      library(purrr)
      
      mytib %>% 
        mutate(html.data = map(mylink, read_html), 
               title = map_chr(html.data,~.x %>% html_nodes('title') %>% html_text)) %>%
        select(-html.data) %>%
        write.csv('data.csv', row.names = FALSE)
      

      【讨论】:

      • 是的,我想保留一切。实际上是 csv 或任何其他格式。谢谢!
      猜你喜欢
      • 1970-01-01
      • 2017-10-12
      • 1970-01-01
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 2019-09-05
      • 1970-01-01
      • 2014-06-03
      相关资源
      最近更新 更多