r: использование purrr :: безопасно для обработки неудачных URL-адресов - PullRequest
1 голос
/ 10 мая 2019

Я пытаюсь создать несколько страниц с rvest и purrr::map. Однако я не уверен, как использовать purrr::safely для обработки неудачных ссылок. Возьмите следующий код:

library(rvest)
library(purrr)
urls <- list("https://en.wikipedia.org/wiki/FC_Barcelona",
             "https://en.wikipedia.org/wiki/Rome",
             "lkjsadajf")
h <- urls %>% map(~{
  Sys.sleep(sample(seq(1, 3, by=0.001), 1))
  read_html(.x)})

Я получаю следующую понятную ошибку:

Error: 'lkjsadajf' does not exist in current working directory ('/home/user').

Как мне использовать purrr::safely или любую другую функцию обработки ошибок для создания списка с html всех urls, которые работают, и с NA с urls, которые не работают?


EDIT

В качестве дополнения к вопросу выше: функция safely создает вложенный список. Как обработать вывод safely, чтобы он обрабатывался rvest::html_nodes?

library(dplyr)
out <- h %>% map_df(~{
  a <- html_nodes(., "#firstHeading") %>% html_text()
  a <- if (length(a) == 0) NA else a
  b <- html_nodes(., ".toctext") %>% html_text()
  b <- if (length(b) == 0) NA else b

  df <- tibble(a, b)
})
out

1 Ответ

2 голосов
/ 10 мая 2019

Один из вариантов - обернуть read_html в safely и указать otherwise как NULL или NA

library(dplyr)
library(purrr)
safe_html <- safely(read_html, otherwise = NULL)
h <- urls %>% 
       map(~{
         Sys.sleep(sample(seq(1, 3, by=0.001), 1))
         safe_html(.x)})

. Мы можем удалить элементы NULL и продолжить с

discard(h, ~ is.null(.x$result)) %>%
        map_df(~ .x$result %>% {
        a <- html_nodes(., "#firstHeading") %>%
              html_text()

        b <- html_nodes(., ".toctext") %>% 
              html_text()
        rowr::cbind.fill(a, b, fill = NA)

        } )
...