使用 httr::url_ok 验证 URL——停留在某些 URL 上并忽略超时

Using httr::url_ok to validate URLs—stuck on certain URLs and timeout ignored

我正在尝试使用 url_okpbsapply 来测试大量 URLs:

pbsapply(foo$URL, function(x) try(url_ok(x)))

但程序一直卡在某些错误的 URL 上,例如 url_ok("www.isdnet.net")。这个 URL 将 return 403 Forbidden 在浏览器中,但会使 R 卡住。还有其他不好的URL情况,不知道大数据集中有多少不好的URL

我试图创造一个暂停,如果几秒钟后不能 return 任何东西,让它停止,给它一个 FALSE 然后继续下一个 URL .

我试过了但是没用,还是卡住了:

evalWithTimeout(url_ok("www.isdnet.net"), timeout=1.08, onTimeout="warning");

不幸的是,HEAD 请求(url_ok 使用的请求)并非在所有 Web 服务器上都有效,并且可能会使您陷入超时死亡漩涡 给你不准确的结果(以及其他问题)。避免这种情况的唯一方法是使用 GET 请求,这将导致下载更多负载。但是,您可能不得不担心格式错误的 URLs(我很少遇到大型、干净的 URL 数据集),这会引发实际的 R 错误。你最好的选择是编写一个更健壮的 "URL OK" 例程(更新以添加 timeout):

library(httr)
library(pbapply)

# this is a dangerous setting for normal operations
set_config(config(ssl_verifypeer=0L, ssl_verifyhost=0L), override=TRUE)

url_ok_via_get <- function(...) {

  ret <- FALSE

  tryCatch( {
x <- GET(..., timeout(5), user_agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.61 Safari/537.36"))
    ret <- identical(status_code(x), 200L)
  }, error=function(e) {
    ret <- FALSE
  }, finally=return(ret))

}

url_ok_via_get("aladslsdf")
## [1] FALSE

url_ok_via_get("http://www.isdnet.net")
## [1] FALSE

url_ok_via_get("http://dds.ec/guaranteed_to_return_404")
## [1] FALSE

url_ok_via_get("http://rud.is/")
## [1] TRUE

url_ok_via_get("http://www.gn.dk")
## [1] FALSE

pbsapply(c("aladslsdf", "http://www.isdnet.net",
           "http://dds.ec/guaranteed_to_return_404", "http://rud.is/",
           "http://www.gn.dk"), url_ok_via_get)

##                              aladslsdf 
##                                  FALSE 
##                  http://www.isdnet.net 
##                                  FALSE 
## http://dds.ec/guaranteed_to_return_404 
##                                  FALSE 
##                         http://rud.is/ 
##                                   TRUE 
##                       http://www.gn.dk 
##                                  FALSE