在R中循环调用气象API获指定时段数据遇报错求助
解决R中循环调用气象API的报错问题
问题概述
需要获取2007-2023年的气象数据,由于API单次返回上限为300000条,仅能获取1-2个月数据,因此计划通过循环每日调用API获取当日12点的观测数据(原数据每10分钟更新,无需全量)。使用ChatGPT提供的循环代码时出现如下报错:
Error in if (httr::http_status(response)$status_code == 200) { : argument is of length zero
相关代码
原始请求代码
base_url <- "https://dmigw.govcloud.dk/v2/" info_url <- "metObs/collections/observation/items?" req_url <- "stationId=06060&&datetime=2007-07-01T12:00:00Z/2008-11-01T12:00:00Z&limit=300000¶meterId=temp_dry" api_key <- "&api-key=34616d8a-08f0-4eec-9887-f3b76c29f773"
ChatGPT提供的循环代码
# Define your start date and end date start_date <- as.Date("2007-07-01") end_date <- Sys.Date() # Today's date # Base API URL and key base_url <- "https://dmigw.govcloud.dk/v2/metObs/collections/observation/items?" api_key <- "&api-key=YOUR_API_KEY" # Replace with your actual API key # Loop through each date while (start_date <= end_date) { # Format the date for the API call formatted_date <- format(start_date, "%Y-%m-%dT12:00:00Z") # Construct the API call URL api_call <- paste0(base_url, "stationId=06060&&datetime=", formatted_date, "&limit=300000¶meterId=temp_dry", api_key) # Make the API call response <- httr::GET(api_call) # Check if the request was successful if (httr::http_status(response)$status_code == 200) { # Parse and process the API response api_content <- httr::content(response, "text") # Add processing logic here cat("API call for date", formatted_date, "was successful.\n") } else { cat("API call for date", formatted_date, "failed with status code", httr::http_status(response)$status_code, "\n") } # Increment date start_date <- start_date + 1 }
报错原因分析
该错误表明httr::http_status(response)$status_code返回了长度为0的结果,通常由以下原因导致:
- 请求失败(如网络中断、API服务器无响应)导致
response对象异常 - URL构造错误(比如代码中的冗余
&&符号,或datetime参数格式不符合API要求) - API密钥无效或权限不足
修正后的代码
library(httr) library(jsonlite) # 配置参数 start_date <- as.Date("2007-07-01") end_date <- as.Date("2023-12-31") # 替换为目标结束日期 api_key <- "34616d8a-08f0-4eec-9887-f3b76c29f773" # 填入实际API密钥 station_id <- "06060" parameters <- c("temp_dry") # 可添加其他变量如"temp_dew", "wind_speed"等 # 初始化数据框存储结果 all_data <- data.frame() # 循环每日请求 while (start_date <= end_date) { formatted_date <- format(start_date, "%Y-%m-%dT12:00:00Z") # 构造URL:修正冗余&&,使用单&分隔参数 api_call <- paste0( "https://dmigw.govcloud.dk/v2/metObs/collections/observation/items?", "stationId=", station_id, "&datetime=", formatted_date, "&limit=1", # 只取当日12点的1条数据,无需30万上限 "¶meterId=", paste(parameters, collapse=","), "&api-key=", api_key ) # 尝试请求,加入错误捕获 tryCatch({ response <- GET(api_call) # 先检查response是否有效 if (!is.null(response)) { status_code <- http_status(response)$status_code if (status_code == 200) { # 解析JSON格式响应 content <- content(response, "parsed") if (!is.null(content$features) && length(content$features) > 0) { # 提取数据并转换为数据框 data_row <- as.data.frame(content$features[[1]]$properties) data_row$date <- start_date all_data <- rbind(all_data, data_row) cat("成功获取", formatted_date, "的数据\n") } else { cat(formatted_date, "无可用数据\n") } } else { cat(formatted_date, "请求失败,状态码:", status_code, "\n") } } else { cat(formatted_date, "请求无响应\n") } }, error = function(e) { cat(formatted_date, "请求出错:", e$message, "\n") }) # 加入1秒延迟,避免触发API限流 Sys.sleep(1) # 日期自增 start_date <- start_date + 1 } # 保存结果到CSV write.csv(all_data, "daily_meteorological_data.csv", row.names = FALSE)
关键修正点
- 修复URL中的冗余
&&,改用标准的&分隔参数 - 加入
tryCatch错误捕获,处理请求过程中的异常 - 先检查
response是否有效,再提取状态码,避免长度为0的错误 - 将
limit设为1(因为只需要当日12点的单条数据),减少不必要的数据传输 - 支持多参数同时请求,无需单独循环每个变量
- 加入延迟
Sys.sleep(1),避免频繁请求触发API限流 - 自动收集并合并所有数据,最终保存为CSV文件
内容的提问来源于stack exchange,提问作者Phung Minh Le
相关产品推荐
相关产品推荐

