运行 POST 请求在 for 循环中获取服务票证

Running a POST request to get a Service Ticket inside a for loop

我正在使用 NIH/NLM REST API 并尝试以编程方式一次提取大量数据。我从来没有使用过使用服务票证(TGT 和 ST)而不是 OAUTH 进行验证的 API,它需要为您发出的每个 GET 请求刷新,所以我不确定我是否会去关于这个正确的方法。非常感谢任何帮助。

这是我目前拥有的代码:

library(httr)
library(jsonlite)
library(xml2)

UTS_API_KEY <- 'MY API KEY'

# post to the CAS endpoint
response <- POST('https://utslogin.nlm.nih.gov/cas/v1/api-key', encode='form', body=list(apikey = 'MY API KEY'))

# print out the status_code and content_type
status_code(response)
headers(response)$`content-type`

doc <- content(response)
action_uri <- xml_text(xml_find_first(doc, '//form/@action'))
action_uri

# Service Ticket
response <- POST(action_uri, encode='form', body=list(service = 'http://umlsks.nlm.nih.gov'))
ticket <- content(response, 'text')
ticket #this is the ST I need for every GET request I make


# build search_uri using the paste function for string concatenation
version <- 'current'
search_uri <- paste('https://uts-ws.nlm.nih.gov/rest/search/', version, sep='')

# pass the the query params into httr GET to get the response 
query_string <- 'diabetic foot'
response <- GET(search_uri, query=list(ticket=ticket, string=query_string))

## print out some of the results
search_uri
status_code(response)
headers(response)$`content-type`


search_results_auto_parsed <- content(response)
search_results_auto_parsed


class(search_results_auto_parsed$result$results)

search_results_data_frame <- fromJSON(content(response,'text'))
search_results_data_frame

此代码仅适用于少数 GET 请求,但是,我正试图提取 300 多个医学术语。例如,在查询字符串中,我想遍历一个字符串数组(例如,“糖尿病”、“血压”、“心血管护理”、“EMT”等)。我需要发出 POST 请求并将 ST 传递到数组中每个字符串的 GET 参数中。

我试过这段代码:

for (i in 1:length(Entity_Subset$Entities)){
  ent = Entity_Subset$Entities[i] #Entities represents my df of strings 
  url <- paste(' https://uts-ws.nlm.nih.gov/rest/search/current?string=',
               ent,'&ticket=', sep = "")
  print(url)
  }

但是在将字符串放入 (GET) HTTPS 请求后,将 POST 和 GET 请求拼凑在一起的运气并不好。

侧边栏:我还尝试在 Postman 中编写一些前置脚本,但奇怪的是,服务票据不像 JSON 那样 return(没有要获取和传递的键值对)。纯文本。

感谢您提供的任何建议!

我认为您可以简单地将 POST 和 GET 请求包装在一个函数中。然后,lapply那个函数到一个字符列表。

library(httr)
library(jsonlite)
library(xml2)

fetch_data <- function(query_string = 'diabetic foot', UTS_API_KEY = 'MY API KEY', version = 'current') {
  response <- POST('https://utslogin.nlm.nih.gov/cas/v1/api-key', encode='form', body=list(apikey = UTS_API_KEY))
  
  # print out the status_code and content_type
  message(status_code(response), "\n", headers(response)$`content-type`)
  action_uri <- xml_text(xml_find_first(content(response), '//form/@action')); message(action_uri)
  
  # Service Ticket
  response <- POST(action_uri, encode = 'form', body=list(service = 'http://umlsks.nlm.nih.gov'))
  ticket <- content(response, 'text'); message(ticket)
  
  # build search_uri using the paste function for string concatenation
  search_uri <- paste0('https://uts-ws.nlm.nih.gov/rest/search/', version)
  # pass the the query params into httr GET to get the response 
  response <- GET(search_uri, query=list(ticket=ticket, string=query_string))
  ## print out some of the results
  message(search_uri, "\n", status_code(response), "\n", headers(response)$`content-type`)
  fromJSON(content(response, 'text'))
}

# if you have a list of query strings, then
lapply(Entity_Subset$Entities, fetch_data, UTS_API_KEY = "blah blah blah")

# The `lapply` above is logically equivalent to
result <- vector("list", length(Entity_Subset$Entities))
for (x in Entity_Subset$Entities) {
  result[[x]] <- fetch_data(x, "blah blah blah")
}