我想从ftp服务器获取多个zip文件。 我可以在以前的帖子的帮助下单独获取zip文件。
但对于所有需要的数据来说,这将是大量的工作。所以我想找到一种自动化的方法。
ftp 如下所示: ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/climate/10_minutes/solar/now/10minutenwerte_SOLAR_01048_now.zip
我想将"01048"更改为最近的加热器站的 ID,因为我已经在数据框(数据(中了。
我以为我可以循环所有需要的电台
for(y in Data$StationsID)) {
urls <- "ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/climate/10_minutes/solar/now/10minutenwerte_SOLAR_{y}_now.zip"))
}
但我只得到"ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/climate/10_minutes/solar/now/10minutenwerte_SOLAR_{y}_now.zip"((
ZIP 数据具有 .txt CSV 分析的理想选择。
稍后我想使用这些文件从德国的不同点获取太阳能数据。 但首先我需要这样的列表,但我不知道如何获得它:
urls
[1] url_1
[2] url_2
.
.
你甚至不需要循环。尝试
urls <- paste0("ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/climate/10_minutes/solar/now/10minutenwerte_SOLAR_", Data$StationsID, "_now.zip")
这将为您提供所有URL的向量。 之后,您可以使用例如lapply
.
results <- lapply(urls, FUN = function(u) {
# FETCH
# UNZIP
# TIDY
# ...
}
(👍🏼第一个问题!
另一种方法如下。
我们:
- 获取所有可能的数据文件
- 仅将其过滤为SOLAR zip数据文件(如果需要,您可以过滤更多 - 即将其限制为现有数据框中的内容(
- 创建保存位置
- 下载文件
请注意,在没有暂停的情况下用连续的请求锤击服务器是非常糟糕的形式,所以这引入了它,但这是这些天经常被忽视的礼貌。
library(curl)
library(httr)
base_dir <- "ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/climate/10_minutes/solar/now/"
# Get all available files in that directory
res <- curl_fetch_memory(base_dir, handle = new_handle(dirlistonly = TRUE)
grep(
"SOLAR_[[:digit:]]{5}",
strsplit(rawToChar(res$content), "n")[[1]], # curl_fetch returns a raw vector since it has no idea what type of content might be there so we have to convert it and it's a text listing so we have to do some more wrangling
value = TRUE
) -> all_zips
head(all_zips)
## [1] "10minutenwerte_SOLAR_00044_now.zip"
## [2] "10minutenwerte_SOLAR_00071_now.zip"
## [3] "10minutenwerte_SOLAR_00073_now.zip"
## [4] "10minutenwerte_SOLAR_00131_now.zip"
## [5] "10minutenwerte_SOLAR_00150_now.zip"
## [6] "10minutenwerte_SOLAR_00154_now.zip"
save_dir <- "~/Data/solar-output"
dir.create(save_dir)
for (zip in all_zips) {
try(httr::GET(
url = sprintf("%s%s", base_dir, zip),
httr::write_disk(file.path(save_dir, zip)), # enables caching (it won't overwrite by default and avoid issues with download.file() on windows)
httr::progress() # progress bars for free!
))
Sys.sleep(5) # be kind to their server CPU and network bandwidth
}
我们将GET()
包装在try()
中,因为我们要求write_disk()
不要覆盖现有文件。发生这种情况时,它会抛出一个异常,以便try()
捕获它并让循环继续(但仍显示有关文件已存在的有用消息(。