首页 > 解决方案 > 从 R 中的图像 URL 异步下载图像

问题描述

我需要在一个月内下载大量图像。

我写了一个脚本,在我的个人机器上以大约 200/秒的速度下载小的 JSON 文本;最终,我将在服务器上运行我的脚本。(不幸的是,我知道图像下载会慢得多。)下面显示的脚本并行进行异步调用,这大约是异步但串行进行这些调用的三倍。

require(crul)
require(tidyverse)
require(tictoc)
require(furrr)

asyncCalls <- function(i) {
    urls_to_call = all_urls[i:min(i + 99, nrow(all_urls))]
    cc <- Async$new(urls = urls_to_call)  # ready the requests
    res <- cc$get()  # make the requests
    lapply(res, function(z) z$parse("utf-8"))  # parse the crul results
}

all_urls <- paste0("http://placehold.it/640x440&text=image", seq(1, 200))

plan(multiprocess)  # use multiple cores
tic()
metadata <- unlist(future_map(seq(0, floor(nrow(all_urls)/100))*100, ~ asyncCalls(.x)))
toc()

正如人们所期望的那样,运行这些图像 URLasyncCalls()会将所有元素返回为NA.

如何修改脚本以允许我从这些 URL 快速下载图像?我在 中找不到文件下载功能crul,也不知道如何异步使用download.file(). 谢谢!

标签: rasynchronousimagedownload

解决方案


crul维护者在这里。

Async支持写入磁盘。您需要传入与 URL 列表长度相同的文件路径列表。例如:

library(crul)
cc <- Async$new(
  urls = c(
    'https://eu.httpbin.org/get?a=5',
    'https://eu.httpbin.org/get?foo=bar',
    'https://eu.httpbin.org/get?b=4',
    'https://eu.httpbin.org/get?stuff=things',
    'https://eu.httpbin.org/get?b=4&g=7&u=9&z=1'
  )
)
files <- replicate(5, tempfile())
res <- cc$get(disk = files)
out <- lapply(files, readLines)

对于您的用例,您没有文本文件,但同样的逻辑适用


推荐阅读