提问人:user2165379 提问时间:8/13/2023 更新时间:8/13/2023 访问量:525
curl::curl_fetch_memory(url, handle = handle) 中的错误:无法解析主机:
Error in curl::curl_fetch_memory(url, handle = handle): Could not resolve host:
问:
在某些情况下,我的 R 代码(见下文)会生成以下错误:
[1] "2023-08-12 16:47:37.463"
Error in curl::curl_fetch_memory(url, handle = handle): Could not resolve host: api.abc.com
Request failed [ERROR]. Retrying in 1.3 seconds...
Error in curl::curl_fetch_memory(url, handle = handle): Could not resolve host: api.abc.com
Request failed [ERROR]. Retrying in 1 seconds...
Error in curl::curl_fetch_memory(url, handle = handle):
Could not resolve host: api.abc.com
api.abc.com 不是我使用的原始 API。 我使用了一个商业 API,它注意到我的服务器在上面的特定时刻没有关闭。在某些情况下,当服务器关闭时,它会返回 http-code 503。
我有两个问题:
- 这些错误的原因可能是什么?
- 在出现这些错误的情况下,如何使下面的脚本继续运行?目前,在这些错误消息之后,它会中断。我没想到会这样,因为我在我的代码中使用了 .
RETRY
GET
我的代码每 10 秒使用调度程序调用一次(请参阅代码末尾)。在此示例代码中,我使用了一个免费的 API (universities.hipolabs.com) 作为示例。tclTaskSchedule
library(httr) # accessing API's'
library(jsonlite) # JSON parsing
library(dplyr)
library(readr)
library(purrr)
library(tidyr)
library(stringr)
library(tibble)
library(tcltk2)
library(lubridate)
run_api_once <- function() {
mydatalist <- list() #create an empty list
my_next_page_with_number <- "http://universities.hipolabs.com/search?country=United+States"
mydata1 <- RETRY("GET", my_next_page_with_number)
if(mydata1$status_code != 200){
print(mydata1$status_code)
http_responses <<- append(http_responses, paste(mydata1$status_code, Sys.time()))
has_more_pages <- FALSE
} else {
rawdata <- rawToChar(mydata1$content)
mydata2 <- fromJSON(rawdata, flatten = FALSE, simplifyVector = FALSE)
mydata <- mydata2
mydatalist <- c(mydatalist, mydata)
}
y <- Sys.time()
y <- format(y, "%Y-%m-%d %H:%M")
print(y)
users <- tibble(user = mydatalist)
myvar <<- users %>% unnest_wider(user)
return(myvar)
}
# call function every 10 seconds:
tclTaskSchedule(10000, run_api_once(), id = "run_api_once", redo = TRUE)
# end session:
tclTaskDelete(NULL)
我想这是无关紧要的,尽管为了完整起见:我使用 Plumber 将 myvar 的内容流式传输到我电脑上的本地服务器。请参阅下面的代码:
# stream df myvar to local api at port 8405:
library(plumber)
pr("D:/plumber_universities2test.R") %>%
# pr("C:/plumber_universities2test.R") %>%
pr_run(port=8405)
它调用此脚本:
library(plumber)
library(dplyr)
#* @param symbol Ticker symbol (just to input something in the function)
#* @get /return
#* @serializer json list(na="string")
universities_data <- function(symbol) {
data <- myvar
data
}
多谢!
答:
1赞
JBGruber
8/13/2023
#1
要回答您的问题,请执行以下操作:
- 有几个可能的原因:您没有连接到互联网;你的防火墙挡住了路,阻止了你;或者您正在向无效的 URL 发出请求。如果没有看到您发出请求的实际 URL,我无法确定,但我猜第三个选项是最有可能的。您应该检查在粘贴特定 URL 时是否犯了错误。例如,代替
httr
"google.comsearch"
"google.com/search"
- 之所以没有按照您预期的方式运行,是因为这不是服务器返回的 HTTP 错误状态,但您的请求根本无法执行。为了演示这种差异,让我们看一下一个简单的函数的行为,该函数向一个 URL 发出请求,该 URL 会自动返回一个 HTTP 错误,而这个 URL 根本不存在:
RETRY
library(httr)
test_fun <- function(u) {
RETRY("GET", u, times = 2)
print("still running")
}
# response contains error
test_fun("https://httpbin.org/status/429")
#> Request failed [429]. Retrying in 1 seconds...
#> [1] "still running"
# no repsonse since there is no server at `test.coms`
test_fun("test.coms")
#> Error in curl::curl_fetch_memory(url, handle = handle): Could not resolve host: test.coms
#> Request failed [ERROR]. Retrying in 1 seconds...
#> Error in curl::curl_fetch_memory(url, handle = handle): Could not resolve host: test.coms
创建于 2023-08-13 with reprex v2.0.2
如您所见,第一个示例仍然执行函数的剩余代码,而第二个示例则因错误而停止。我建议仔细检查为什么请求没有到达服务器,如果您确定没有更好的方法,您可以绕行:try
RETRY
mydata1 <- try(RETRY("GET", my_next_page_with_number))
if (is(mydata1, "try-error")) mydata1 <- list(status_code = 404)
if(mydata1$status_code != 200){
# your code ...
}
但在我看来,这种行为是正确的,因为它不仅仅是忽略代码或互联网配置中可能存在的错误(不是服务器端问题)。RETRY
评论
0赞
user2165379
8/14/2023
@JBGruber ,非常感谢您的广泛回答!在发布我现在意识到的问题之前,我应该自己测试更多。我将检查我的 URL 中是否有错误的可能性,然后回来。
0赞
user2165379
8/14/2023
@JBGruber ,我的代码中来自 API 的 URL 是硬编码的,只是我在 URL 中添加了分页。我测试了错误的页码,这不会给出错误。尽管其他程序继续运行,但可能会丢失互联网连接。是否有可能来自 API 的服务器过载以至于它没有给出任何响应,从而导致错误?无论如何,您的解决方案运行完美!我对此感到非常满意,它解决了我的问题。特别是因为这个问题并不经常发生,尽管当它发生时,我的代码挂起。多谢!
评论