如何在R中批量下载WorldPop UK站点文件(规避RSelenium)
解决WorldPop数据集R批量下载的跳转链接问题
我明白你遇到的痛点了——手动批量下载WorldPop的多国数据集实在太耗时,而且浏览器里能用的直接下载链接,放到R里用download.file或者curl_download就失效,核心问题就是这些链接需要服务器跳转,而基础下载函数没法处理会话和跳转逻辑。下面给你一套基于httr和rvest的解决方案,不需要依赖RSelenium,代码简洁易分享。
为什么直接链接失效?
WorldPop的下载链接并不是直接指向文件的URL,而是触发服务器内部跳转的接口。浏览器会自动处理跳转并维持会话状态(比如cookie),但download.file默认不会跟进跳转,也不会保存会话信息,导致请求被服务器拒绝。
解决方案步骤
1. 安装并加载必要的包
我们需要用httr来处理会话和跳转请求,rvest来解析页面中的下载链接:
install.packages(c("httr", "rvest", "stringr")) library(httr) library(rvest) library(stringr)
2. 解析文件索引页面,提取所有下载链接
以尼日利亚的文件索引页面为例,先获取页面内容,定位并提取所有下载链接:
# 目标索引页面URL index_url <- "http://www.worldpop.org.uk/data/files/index.php?dataset=140&action=dir" # 创建会话(维持cookie等会话信息,模拟浏览器行为) wp_session <- session(index_url) # 读取页面并解析下载链接 download_links <- wp_session %>% read_html() %>% # 定位包含下载动作的a标签 html_elements("a[href*='action=download']") %>% html_attr("href") %>% # 补全完整URL(页面里的链接是相对路径) paste0("http://www.worldpop.org.uk/data/files/", .)
3. 批量下载文件
编写一个函数来批量处理下载,自动处理跳转并保存文件:
batch_download_worldpop <- function(links, save_dir = "./worldpop_datasets") { # 创建保存目录(如果不存在) if (!dir.exists(save_dir)) { dir.create(save_dir, recursive = TRUE) } # 遍历每个链接下载 for (link in links) { # 从链接中提取文件名(根据实际文件后缀调整,这里假设是txt) file_id <- str_extract(link, "file=\\d+") %>% str_remove("file=") filename <- paste0("worldpop_file_", file_id, ".txt") # 发送请求,自动跟进跳转 response <- wp_session %>% GET(link) # 检查请求是否成功 if (response$status_code == 200) { # 以二进制形式保存文件(兼容多种文件类型) writeBin(content(response, "raw"), file.path(save_dir, filename)) cat("✅ 成功下载:", filename, "\n") } else { cat("❌ 下载失败:", link, "状态码:", response$status_code, "\n") } } } # 执行批量下载 batch_download_worldpop(download_links)
4. 测试单个链接
针对你提供的测试链接,可以单独验证:
test_link <- "http://www.worldpop.org.uk/data/files/index.php?dataset=140&action=download&file=60" test_response <- wp_session %>% GET(test_link) writeBin(content(test_response, "raw"), "./test_download.txt")
关键说明
- 会话维持:用
session()创建的会话会保存cookie等信息,模拟浏览器访问的状态,确保服务器能正确响应下载请求。 - 自动跳转:
httr::GET默认开启follow_redirects=TRUE,会自动处理服务器的跳转逻辑。 - 二进制保存:用
writeBin保存内容,避免因文件编码问题导致下载的文件损坏。
内容的提问来源于stack exchange,提问作者Neal Barsch
相关产品推荐
相关产品推荐

