我试图从网络API中获取R中的数据(推断媒体,具体)
我的案例中的GET请求已成功处理。但是,POST有问题
请求包含数据,这些数据将被处理并随后返回。这两种都是json格式。
api文档中的示例代码如下:
curl -v -X GET "https://api.infermedica.com/v2/symptoms"
使用curl在R中执行此操作,我使用:
h <- new_handle()
handle_setheaders(h, 'app_id' = "id", 'app_key' = "key", 'Accept' = "application/json" )
curl_fetch_memory("https://api.infermedica.com/v2/symptoms", handle = h)
这只能发送标题。但是,对于POST主体这样的复杂请求,我觉得我最好不要使用httr,我找不到使用curl发送身体数据的方法
使用httr执行的相同查询如下:
GET(url = "https://api.infermedica.com/v2/symptoms", verbose(),add_headers(app_id = "id", app_key = "key", 'Accept' = "application/json"))
这也有效。然后是POST请求
包含json的数据的文档代码如下所示:
curl -v -X POST -H "Content-Type:application/json" "https://api.infermedica.com/v1/diagnosis" -d '{"sex": "male", "age": 29, "evidence": [ { "id": "s_21", "choice_id": "present" } ] }'
为此,我创建了我的json:
bod <- list(sex = jsonlite::unbox('male'), age = jsonlite::unbox('26'), evidence = data.frame(id = "s_21", choice_id = 'present'))
如果您注意到,证据信息将作为数据框创建。这样做的原因是,当我将其更改为json时,它看起来与文档中的文本json完全相同。这就是我的意思:
POST(url = "https://api.infermedica.com/v1/diagnosis", body = bod ,
encode = 'json', verbose(),
add_headers(app_id = "id", app_key = "key", 'Content-Type:' = "application/json"))
此请求的详细信息是:
POST / v1 /诊断HTTP / 1.1
{&#34;性别&#34;:&#34;男性&#34;&#34;年龄&#34;:&#34; 26&#34;&#34;证据&#34 ;:[{&#34; ID&#34;:&#34; s_21&#34;&#34; choice_id&#34;:&#34;本&#34;}]}
HTTP / 1.1 400错误请求
查看身体数据的行: -
{&#34;性别&#34;:&#34;男性&#34;&#34;年龄&#34;:&#34; 26&#34;&#34;证据&#34;:[ {&#34; ID&#34;:&#34; s_21&#34;&#34; choice_id&#34;:&#34;本&#34;}]}
api如何决定它应该是什么样的。
但是,但是,错误的请求错误被抛到我身上。 我尝试使用嵌套列表作为正文,但没有任何好处。从文档页面复制粘贴json字符串并将其传递给它也会产生相同的错误。 当然,当我从终端运行cURL命令时,请求会被处理,这意味着我将json数据传递给服务器的方式有问题
非常感谢任何帮助
答案 0 :(得分:1)
这可能有助于您入门:
library(httr)
library(jsonlite)
library(dplyr)
im_info <- function() {
res <- GET("https://api.infermedica.com/v2/info",
add_headers(app_id=Sys.getenv("INFERMEDICA_APP_ID"),
app_key=Sys.getenv("INFERMEDICA_APP_KEY")))
stop_for_status(res)
content(res, as="text", encoding="UTF-8") %>%
fromJSON(flatten=TRUE)
}
im_list_symptoms <- function() {
res <- GET("https://api.infermedica.com/v2/symptoms",
add_headers(app_id=Sys.getenv("INFERMEDICA_APP_ID"),
app_key=Sys.getenv("INFERMEDICA_APP_KEY")))
stop_for_status(res)
content(res, as="text", encoding="UTF-8") %>%
fromJSON(flatten=TRUE)
}
im_get_symptom <- function(symptom_id="s_277") {
res <- GET(sprintf("https://api.infermedica.com/v2/symptoms/%s", symptom_id),
add_headers(app_id=Sys.getenv("INFERMEDICA_APP_ID"),
app_key=Sys.getenv("INFERMEDICA_APP_KEY")))
stop_for_status(res)
content(res, as="text", encoding="UTF-8") %>%
fromJSON(flatten=TRUE)
}
im_start_diagnosis <- function() {
return(list(age=NULL, sex=NULL))
}
im_add_patient_info <- function(diag_obj, age, sex) {
diag_obj$age <- unbox(as.numeric(age))
diag_obj$sex <- unbox(sex)
diag_obj
}
im_add_evidence <- function(diag_obj, id, choice=c('present', 'absent', 'unknown')) {
choice <- match.arg(choice, c('present', 'absent', 'unknown'))
df <- data_frame(id=id, choice_id=choice)
if (length(diag_obj$evidence) == 0) {
diag_obj$evidence <- df
} else {
bind_rows(diag_obj$evidence, df)
}
diag_obj
}
im_get_diagnosis <- function(diag_obj) {
res <- POST("https://api.infermedica.com/v2/diagnosis",
add_headers(app_id=Sys.getenv("INFERMEDICA_APP_ID"),
app_key=Sys.getenv("INFERMEDICA_APP_KEY")),
body=diag_obj,
encode="json",
verbose())
stop_for_status(res)
content(res, as="text", encoding="UTF-8") %>%
fromJSON(flatten=TRUE)
}
im_start_diagnosis() %>%
im_add_patient_info(29, "male") %>%
im_add_evidence("s_21", "present") %>%
im_get_diagnosis()
您现在可以使用alpha包:infermedica