Как мне получить код ошибки HTTP из запроса download.file? - PullRequest
0 голосов
/ 18 декабря 2018

Этот код пытается загрузить страницу, которая не существует:

url <- "https://en.wikipedia.org/asdfasdfasdf"
status_code <- download.file(url, destfile = "output.html", method = "libcurl")

Возвращает ошибку 404:

trying URL 'https://en.wikipedia.org/asdfasdfasdf'
Error in download.file(url, destfile = "output.html", method = "libcurl") : 
  cannot open URL 'https://en.wikipedia.org/asdfasdfasdf'
In addition: Warning message:
In download.file(url, destfile = "output.html", method = "libcurl") :
  cannot open URL 'https://en.wikipedia.org/asdfasdfasdf': HTTP status was '404 Not Found'

, но переменная code по-прежнему содержит 0,несмотря на то, что в документации для download.file указано, что возвращаемое значение:

(невидимый) целочисленный код, 0 для успеха и ненулевое значение для ошибки.Для методов "wget" и "curl" это код состояния, возвращаемый внешней программой.«Внутренний» метод может возвращать 1, но в большинстве случаев выдает ошибку.

Результаты будут такими же, если я использую curl или wget в качестве метода загрузки.Что мне здесь не хватает?Является ли единственная возможность вызвать warnings() и проанализировать вывод?

Я видел другие вопросы об использовании download.file, но ни один (который я могу найти), который на самом деле не извлекаетКод состояния HTTP.

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Если вы не возражаете против использования другого метода, вы можете попробовать GET из пакета httr:

url_200 <- "https://en.wikipedia.org/wiki/R_(programming_language)"
url_404 <- "https://en.wikipedia.org/asdfasdfasdf"

# OK
raw_200 <- httr::GET(url_200)
raw_200$status_code
#> [1] 200

# Not found
raw_404 <- httr::GET(url_404)
raw_404$status_code
#> [1] 404

Создано в 2019-01-02 Представить пакет (v0.2.1)

0 голосов
/ 30 декабря 2018

Вероятно, лучший вариант - использовать библиотеку cURL напрямую, а не через оболочку download.file, которая не предоставляет полную функциональность cURL.Мы можем сделать это, например, с помощью пакета RCurl (хотя другие пакеты, такие как httr или системные вызовы, также могут достичь того же).Использование cURL напрямую позволит вам получить доступ к информации о cURL, включая код ответа.Например:

library(RCurl)
curl = getCurlHandle()
x = getURL("https://en.wikipedia.org/asdfasdfasdf", curl = curl)
write(x, 'output.html')
getCurlInfo(curl)$response.code
# [1] 404

Хотя первый вариант выше намного чище, если вы действительно хотите использовать download.file, одним из возможных способов было бы перехватить предупреждение с помощью withCallingHandlers

try(withCallingHandlers( 
  download.file(url, destfile = "output.html", method = "libcurl"),
  warning = function(w) {
    my.warning <<- sub(".+HTTP status was ", "", w)
    }),
  silent = TRUE)

cat(my.warning)
'404 Not Found'
...