You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言如何创建map函数同时遍历接口地址与请求体执行批量API调用

R 批量遍历两个列表执行API请求的最优实现

问题描述

首先,如下是数据集的dput输出结果:

df <- structure(list(Id = 111323317:111323326, TypeId = c(37L, 
37L, 37L, 37L, 37L, 37L, 37L, 37L, 37L, 37L), PlayerId = c(458228L, 
458228L, 458228L, 458228L, 458228L, 458228L, 458228L, 458228L, 
458228L, 458228L), TeamId = c(1866215L, 1866214L, 1866215L, 
1866215L, 1866215L, 1866215L, 1866214L, 1866215L, 1866215L, 1866215L
)), row.names = c(NA, -10L), class = "data.frame")

接下来我们将各列数据提取为独立向量:

Ids <- df$Id
TypeIds <- df$TypeId
PlayerIds <- df$PlayerId
TeamIds <- df$TeamId

随后我们引用上述值构建API调用的请求体参数:

data_players = paste0(' { "Context": { "TypeId": "', TypeIds, '" }, "responses": [ { "type": "Players", "PlayerId": "', PlayerIds, '", "TeamId": "', TeamIds, '" } ] } ')

接下来我们使用Ids生成待调用的API地址列表:

api_urls <- sprintf('https://api.sports.com/players/%s/stats', Ids)

最后我们执行API调用(出于保密原因此处为示例地址,非真实接口地址):

get_data <- POST(api_urls[1], add_headers(.headers=headers_upsert), body = data_players)

显然上述示例仅会调用api_urls列表中的第一个地址。我希望创建一个map函数,同时遍历data_players和api_urls两个列表完成批量请求,请问最高效的实现方式是什么?

解决方案

基础单线程实现

针对两个等长序列的同步遍历场景,purrr包的map2系列函数是最简洁高效的原生实现:

library(httr)
library(purrr)

# 批量请求,返回所有响应结果的列表
all_responses <- map2(
  .x = api_urls, 
  .y = data_players, 
  .f = ~POST(.x, add_headers(.headers = headers_upsert), body = .y)
)

如果需要直接解析返回结果并合并为数据框,可以使用map2_dfr:

all_result_df <- map2_dfr(api_urls, data_players, function(url, body) {
  resp <- POST(url, add_headers(.headers = headers_upsert), body = body)
  # 请求成功则解析返回内容,失败则返回空跳过
  if (http_status(resp)$category == "Success") {
    content(resp, "parsed")
  } else {
    NULL
  }
})

并行优化实现(IO密集型场景提速明显)

API请求属于IO密集型任务,多线程并行可以大幅降低总耗时,使用furrr包的并行映射函数仅需修改少量代码:

library(httr)
library(furrr)

# 开启多线程,workers参数为并发请求数,不要超过接口的频率限制
plan(multisession, workers = 4)
all_responses <- future_map2(
  api_urls, 
  data_players, 
  ~POST(.x, add_headers(.headers = headers_upsert), body = .y)
)
# 执行完成后关闭并行进程
plan(sequential)

额外优化建议

不推荐用paste0拼接JSON请求体,很容易出现转义错误,改用jsonlite包自动生成更稳妥:

library(jsonlite)
data_players <- pmap(df, function(TypeId, PlayerId, TeamId, ...) {
  toJSON(
    list(
      Context = list(TypeId = as.character(TypeId)),
      responses = list(list(type = "Players", PlayerId = as.character(PlayerId), TeamId = as.character(TeamId)))
    ), 
    auto_unbox = TRUE
  )
})

内容的提问来源于stack exchange,提问作者user6855566

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 06:36:00