构建R循环捕获API JSON并处理异常,及识别JSON错误的while函数
解决R中API循环请求的错误处理与重试问题
我发现你当前的代码里有个容易忽略的小问题——你先用GET()发送了请求,之后又用getURL()重新请求了同一个API地址,这既浪费API调用次数,也会拖慢运行速度。咱们先把这个问题修正,再加入错误处理和while重试的逻辑,让你的循环更健壮。
一、带重试机制的while循环实现
我们可以用tryCatch()捕获请求过程中的各类错误,再结合while循环实现自动重试,同时设置最大重试次数避免无限循环。下面是优化后的完整代码:
library(httr) library(rjson) # 配置关键参数:最大重试次数、重试间隔 max_retries <- 5 retry_delay <- 2 # 单位:秒 # 初始化列表存储结果(比循环中反复rbind数据框高效得多) results_list <- list() for(j in 1:700){ tx_id <- bloco_i_final$tx[j] tx_url <- paste0("https://example.com/api/", tx_id) request_success <- FALSE retry_count <- 0 # While循环:直到请求成功,或达到最大重试次数 while(!request_success && retry_count < max_retries){ tryCatch({ # 仅发送一次请求,避免重复调用API response <- GET(tx_url, add_headers(Authorization = full_token, Accept = header_type), timeout(120), verbose()) # 自动检查HTTP状态码(比如404、500这类错误会直接触发捕获) stop_for_status(response) # 解析JSON内容 content_text <- content(response, type = 'text', encoding = "UTF-8") parsed_data <- rjson::fromJSON(content_text) # 走到这一步说明请求+解析都成功了 request_success <- TRUE results_list[[j]] <- parsed_data }, error = function(e){ # 打印错误信息方便调试 message(paste("[条目", j, "]请求", tx_id, "失败:", e$message)) retry_count <<- retry_count + 1 message(paste("准备第", retry_count, "次重试...")) # 重试前加延迟,避免触发API限流 Sys.sleep(retry_delay) }) } # 所有重试都失败时,记录并跳过该条目 if(!request_success){ message(paste("[条目", j, "]请求", tx_id, "多次重试后仍失败,已跳过")) results_list[[j]] <- NULL } } # 最后将列表合并为数据框(根据你的数据结构调整as.data.frame的逻辑) final_dataframe <- do.call(rbind, lapply(results_list, as.data.frame))
二、关键优化点说明
- 避免重复请求:移除了多余的
getURL()调用,直接复用httr::GET()的返回结果解析,减少不必要的API调用。 - 全面错误捕获:既捕获网络请求失败(比如超时、连接中断),也通过
stop_for_status()捕获API返回的错误状态码(如401权限错误、500服务器错误)。 - 可控重试逻辑:通过
max_retries限制重试次数,retry_delay设置重试间隔,避免因频繁请求被API限流。 - 高效数据存储:先用列表存储每个请求的结果,最后再合并为数据框,比循环中反复
rbind效率提升明显(尤其是700条数据的规模)。
三、额外实用建议
- 日志记录:如果需要长期追踪错误,可以把错误信息写入日志文件(比如用
write.table()),而不是只打印到控制台。 - 批量请求:如果目标API支持批量查询,可以尝试一次性传入多个
tx值,减少循环次数,大幅提升效率。 - 异步请求:对于超大量API请求,可尝试用
future或httr2的异步功能并行处理,进一步节省时间。
内容的提问来源于stack exchange,提问作者João Machado
相关产品推荐
相关产品推荐

