如何在purrr的as_mapper()中按需调用Sys.sleep()控制API下载频率
解决API下载限速问题:在purrr下载流程中添加定时休眠
问题描述
我需要通过API下载并重命名图片,该API限制每分钟最多下载30张。希望每下载到第30、60、90张等节点时暂停,规避限制。目前用purrr包的as_mapper()写了下载函数,配合pwalk()执行下载,数据框包含图片URL、目标路径,现在已经添加了计数列n,想知道能不能在as_mapper()里嵌入Sys.sleep(),只在n是30的倍数时执行休眠?
当前下载函数代码:
# download function download_name_photos <- as_mapper( ~GET( ..1, # photo url add_headers("Authorization" = paste("Bearer", token)), write_disk( ..2, # photo destination overwrite = TRUE ) ) ) # now download photos using pwalk() photo_df %>% pwalk(download_name_photos)
示例带计数列的数据框:
tribble( ~photo_url, ~photo_destination, ~n, 'https:://blah-blah-1', 'photo1.jpg', '1', 'https:://blah-blah-2', 'photo2.jpg', '2', 'https:://blah-blah-3', 'photo3.jpg', '3' )
解决方案
完全可以实现,只需在下载函数中加入对计数列n的判断逻辑,当n为30的整数倍时调用Sys.sleep()(这里休眠60秒匹配API的每分钟限制)。注意先把示例中字符型的n列转换为数值型,否则判断会出错。
修改后的代码(基于原as_mapper写法)
# 先将n列转换为数值型 photo_df$n <- as.numeric(photo_df$n) # 更新下载函数,加入休眠逻辑 download_name_photos <- as_mapper( ~{ # 执行下载请求 GET( ..1, # photo url add_headers("Authorization" = paste("Bearer", token)), write_disk( ..2, # photo destination overwrite = TRUE ) ) # 当n是30的倍数时,休眠60秒 if (..3 %% 30 == 0) { message(paste("已下载", ..3, "张,休眠60秒规避限速...")) Sys.sleep(60) } } ) # 执行下载 photo_df %>% pwalk(download_name_photos)
更稳妥的按列名传递写法(不受列顺序影响)
如果担心后续数据框列顺序变化导致出错,建议直接在pwalk中使用命名参数的匿名函数,可读性更强:
# 确保n列是数值型 photo_df$n <- as.numeric(photo_df$n) # 直接用匿名函数定义逻辑,按列名传递参数 photo_df %>% pwalk(function(photo_url, photo_destination, n) { # 执行下载 GET( photo_url, add_headers("Authorization" = paste("Bearer", token)), write_disk(photo_destination, overwrite = TRUE) ) # 休眠判断 if (n %% 30 == 0) { message(paste("已下载", n, "张,休眠60秒规避限速...")) Sys.sleep(60) } })
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

