как записать на диск фрейм данных, содержащий html данных? - PullRequest
0 голосов
/ 12 июля 2020

Рассмотрим этот простой пример

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 правильно содержит html код двух разных страниц Википедии, хранящихся в столбце mylink. Проблема в том, что я не могу сохранить этот тяжелый парсинг на диск. Простой 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

Что мне делать? В каком формате я должен хранить свои данные? Спасибо!

Ответы [ 2 ]

1 голос
/ 12 июля 2020

Причина этого обсуждалась здесь . В качестве обходного пути вы можете преобразовать xmlDo c в строку, чтобы сохранить ее:

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>
1 голос
/ 12 июля 2020

Вам действительно нужно хранить все 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...