我正在尝试使用httr包将数据直接从API提取到R中。该API不需要任何身份验证,并且接受lat,long,海拔,变量集和时间段的JSON字符串来估计任何位置的气候变量。这是我第一次使用API,但是下面的代码是我从各种Stack Overflow帖子中拼凑而成的。
library(jsonlite)
library(httr)
url = "http://apibc.climatewna.com/api/clmApi"
body <- data.frame(lat = c(48.98,50.2), ##two example locations
lon = c(-115.02, -120),
el = c(1000,100),
prd = c("Normal_1961_1990.nrm","Normal_1961_1990.nrm"),
varYSM = c("Y","SST"))
requestBody <- toJSON(list("output" = body),auto_unbox = TRUE) ##convert to JSON string
result <- POST("http://apibc.climatewna.com/api/clmApi", ##post to API
body = requestBody,
add_headers(`Content-Type`="application/json"))
content(result)
我尝试了各种不同的版本(例如,手动编写JSON字符串,使用encode = "json"
将正文作为列表放置在POST中),它始终运行,但是内容始终包含以下错误消息:
$Message
[1] "An error has occurred."
$ExceptionMessage
[1] "Object reference not set to an instance of an object."
$ExceptionType
[1] "System.NullReferenceException"
如果我使用GET并直接在URL中指定变量
url = "http://apibc.climatewna.com/api/clmApi/LatLonEl?lat=48.98&lon=-115.02&el=1000&prd=Normal_1961_1990&varYSM=Y"
result <- GET(url)
content(result)
它会产生正确的输出,但是我一次只能获得一个位置的信息。目前尚无关于此API的公开文档,因为它很新,但是我在下面附上了使用JS对其进行解释的部分草稿。非常感谢您对我所提供的帮助/建议。我做错了! 谢谢!
答案 0 :(得分:0)
主要问题是<!-- The form that I need to post -->
<!DOCTYPE html>
<html>
<head>
<title>PublicFiles - Register</title>
</head>
<body>
<h1>Register</h1>
<form action="process.php" method="post">
<input type="text" name="uname" placeholder="Screen Name..."><br>
<input type="password" name="pword" placeholder="Password..."><br>
<input type="email" name="email" placeholder="Email..."><br>
<input type="submit" value="Sign Up">
</form>
</body>
</html>
在将数据发送到API之前使用jQuery.ajax
对数据进行编码,因此它发送的内容类似于jQuery.param
。我不知道R中的某个程序包的编码与[0][lat]=48.98&[0][lon]=-115.02...
类似,所以我们必须一起破解一些东西。
稍微修改您的示例:
jQuery.param
现在,我们进行编码,就像这样:
library(httr)
body <- data.frame(lat = c(48.98,50.2), ##two example locations
lon = c(-115.02, -120),
el = c(1000,100),
prd = c("Normal_1961_1990","Normal_1961_1990"),
varYSM = c("Y","Y"))
所以现在out <- sapply(1:nrow(body), function(i) {
paste(c(
paste0(sprintf("[%d][lat]", i - 1), "=", body$lat[i]),
paste0(sprintf("[%d][lon]", i - 1), "=", body$lon[i]),
paste0(sprintf("[%d][el]", i - 1), "=", body$el[i]),
paste0(sprintf("[%d][prd]", i - 1), "=", body$prd[i]),
paste0(sprintf("[%d][varYSM]", i - 1), "=", body$varYSM[i])
), collapse = "&")
})
out <- paste(out, collapse = "&")
是API所喜欢的形式。最后
out
注意result <- POST(url = "http://apibc.climatewna.com/api/clmApi", ##post to API
body = out,
add_headers(`Content-Type`="application/x-www-form-urlencoded"))
。我们得到
Content-Type