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

求助:用R的rvest包批量下载指定网页2023文件夹文件失败

问题分析与解决方案

你的代码核心问题是HTML节点选择错误,导致未抓取到正确的文件下载链接,最终下载的是网页而非目标ZIP文件。以下是具体修正步骤:

问题点拆解

  • 错误使用context-menu-list-context-menu-root作为选择器,该节点并非文件链接所在标签
  • 链接拼接逻辑有误,未正确处理相对路径
  • 未验证抓取到的URL有效性,导致下载错误内容

修正后的代码

1. 优先抓取2023年文件

library(rvest)
library(dplyr)

# 目标年份(优先2023)
target_year <- 2023
base_url <- "https://www.coes.org.pe/Portal/PostOperacion/Reportes/Ieod"
year_path <- sprintf("Post%%20Operaci%%C3%%B3n/Reportes/IEOD/%d/", target_year)
page_url <- sprintf("%s?path=%s", base_url, URLencode(year_path, reserved = TRUE))

# 读取页面并抓取正确的文件链接
page <- read_html(page_url)
# 关键:选择文件列表中的a标签(匹配页面实际结构)
urls <- page %>% 
  html_nodes(".file-item a") %>% 
  html_attr("href") %>% 
  # 筛选.htm结尾的文件链接
  grep("\\.htm$", ., value = TRUE) %>% 
  # 替换后缀为.zip
  sub("\\.htm$", ".zip", .) %>% 
  # 拼接完整URL
  paste0(base_url, .)

# 创建存储目录
dir <- file.path(tempdir(), "COES")
if (!dir.exists(dir)) dir.create(dir)

# 批量下载文件
if (length(urls) > 0) {
  lapply(urls, function(url) {
    dest_file <- file.path(dir, basename(url))
    download.file(url, dest_file, mode = "wb") # 二进制模式避免ZIP损坏
    cat(sprintf("已下载:%s\n", basename(url)))
  })
  
  # 查看下载结果
  cat("\n下载的文件列表:\n")
  print(list.files(dir))
} else {
  cat("未找到任何可下载的文件链接,请检查页面结构是否变化。")
}

2. 扩展抓取2021-2023年所有文件

如果需要批量处理三年的文件,可添加循环:

library(rvest)
library(dplyr)

base_url <- "https://www.coes.org.pe/Portal/PostOperacion/Reportes/Ieod"
target_years <- 2021:2023
dir <- file.path(tempdir(), "COES")
if (!dir.exists(dir)) dir.create(dir)

for (year in target_years) {
  cat(sprintf("\n开始处理%d年文件...\n", year))
  year_path <- sprintf("Post%%20Operaci%%C3%%B3n/Reportes/IEOD/%d/", year)
  page_url <- sprintf("%s?path=%s", base_url, URLencode(year_path, reserved = TRUE))
  
  page <- read_html(page_url)
  urls <- page %>% 
    html_nodes(".file-item a") %>% 
    html_attr("href") %>% 
    grep("\\.htm$", ., value = TRUE) %>% 
    sub("\\.htm$", ".zip", .) %>% 
    paste0(base_url, .)
  
  if (length(urls) > 0) {
    lapply(urls, function(url) {
      dest_file <- file.path(dir, sprintf("%d_%s", year, basename(url)))
      download.file(url, dest_file, mode = "wb")
      cat(sprintf("已下载:%s\n", basename(url)))
    })
  } else {
    cat(sprintf("%d年未找到可下载文件\n", year))
  }
}

# 查看所有下载文件
cat("\n所有下载文件:\n")
print(list.files(dir))

关键说明

  • 节点选择器:.file-item a是基于目标页面实际HTML结构设置的,若页面后续更新,需重新检查并调整选择器
  • 二进制下载:添加mode = "wb"确保ZIP文件以二进制模式下载,避免文件损坏
  • URL编码:使用URLencode处理路径中的特殊字符(如西班牙语重音),保证页面URL有效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:33:28