您可以在下载前使用httr::HEAD 确定数据大小。请注意,这为您节省了下载的“痛苦”;如果服务器端有任何费用,即使你不下载它也会感到查询痛苦。 (这两个看起来足够快,也许这不是问题。)
# good data
res1 <- httr::HEAD("http://weather.uwyo.edu/cgi-bin/sounding?region=naconf&TYPE=TEXT%3ALIST&YEAR=2021&MONTH=12&FROM=3000&TO=3000&STNM=72645")
httr::headers(res1)$`content-length`
# [1] "9435"
# no data
res2 <- httr::HEAD("http://weather.uwyo.edu/cgi-bin/sounding?region=naconf&TYPE=TEXT%3ALIST&YEAR=1970&MONTH=12&FROM=3000&TO=3000&STNM=72645")
httr::headers(res2)$`content-length`
# NULL
如果 API 提供了用于估计大小(或至少存在数据)的函数,那么远程端使用该函数而不是使用此技术可能会更好。例如:假设 API 调用需要 20 秒的 SQL 查询。调用HEAD 需要20 秒,就像调用GET 一样,唯一的区别是你没有得到数据。如果您看到您将获取数据然后随后调用httr::GET(.),那么您将再等待 20 秒(除非远程端正在缓存查询)。
或者,他们可能有一个启发式来查找数据的存在,也许只是一个简单的是/否,只需要几秒钟。在这种情况下,在调用 20 秒的完整查询调用之前进行 3 秒的“数据是否存在”API 调用会“更好”。
底线:如果 API 有“数据大小”估算器,请使用它,否则 HEAD 应该可以正常工作。
作为HEAD 的替代品,只需GET 数据,检查内容长度,并仅在找到时才保存到文件:
res1 <- httr::GET("http://weather.uwyo.edu/cgi-bin/sounding?region=naconf&TYPE=TEXT%3ALIST&YEAR=2021&MONTH=12&FROM=3000&TO=3000&STNM=72645")
stuff <- as.character(httr::content(res1))
if (!is.null(httr::headers(res1)$`content-length`)) {
writeLines(stuff, "somefile.html")
}
# or do something else with the results, in-memory