如何从download.file请求中捕获HTTP错误代码?

Mic*_*l A 7 curl r http wget

此代码尝试下载不存在的页面:

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

这会返回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'
Run Code Online (Sandbox Code Playgroud)

但是code变量仍然包含0,即使download.file返回值为的状态的文档是:

一个(不可见的)整数代码,0表示成功,非零表示失败.对于"wget"和"curl"方法,这是外部程序返回的状态代码."internal"方法可以返回1,但在大多数情况下会抛出错误.

如果我使用curlwget作为下载方法,结果是相同的.我在这里错过了什么?是调用warnings()和解析输出的唯一选项吗?

我已经看到了有关使用的其他问题download.file,但没有(我能找到)实际检索HTTP状态代码.

dww*_*dww 5

可能最好的选择是直接使用 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
Run Code Online (Sandbox Code Playgroud)

尽管上面的第一个选项更清晰,但如果您真的想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'
Run Code Online (Sandbox Code Playgroud)


Bir*_*ger 5

如果您不介意使用不同的方法,可以尝试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
Run Code Online (Sandbox Code Playgroud)

由reprex 包(v0.2.1)于 2019-01-02 创建