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

使用R语言批量下载SSOAR平台PDF时遇下载失败问题

批量下载SSOAR资源库PDF文件失败问题

问题描述

  • 需求:从SSOAR资源库的筛选结果中,批量下载约1200个2000-2022年《Historical Social Research》期刊的PDF文件
  • 现有代码问题:要么无法下载文件,要么每次仅下载一篇且覆盖之前的文件
  • 运行警告:出现50+条警告,提示URL对应的目标文件名包含无效参数、无法打开文件,且下载存在非零退出状态

原代码如下:

library(tidyverse)
library(rvest)

url <- "https://www.ssoar.info/ssoar/discover?scope=/&sort_by=score&order=desc&rpp=100&filtertype_0=dateIssued&filter_relational_operator_0=equals&filter_0=%5B2000+TO+2022%5D&filtertype=journal&filter_relational_operator=equals&filter=Historical+Social+Research"
page <- read_html(url)

urls_pdf <- page %>% 
  html_elements("a") %>% 
  html_attr("href") %>% 
  str_subset("\\.pdf") 

urls_pdf[1:100] %>% walk2(basename(.), download.file, mode = "wb")

dir(pattern = "\\.pdf")

解决方案

1. 核心问题分析

  • 文件名非法:basename(urls_pdf)会保留URL中的查询参数(比如?sequence=1),这些参数包含?等系统不允许的文件名字符,导致无法创建文件
  • 未处理分页:原代码仅爬取第一页的100条链接,无法获取全部1200个文件的URL
  • 无错误处理:单个下载失败会抛出警告,且可能中断后续任务

2. 修改后的代码

library(tidyverse)
library(rvest)

# 基础URL模板,替换page参数实现分页
base_url <- "https://www.ssoar.info/ssoar/discover?scope=/&sort_by=score&order=desc&rpp=100&filtertype_0=dateIssued&filter_relational_operator_0=equals&filter_0=%5B2000+TO+2022%5D&filtertype=journal&filter_relational_operator=equals&filter=Historical+Social+Research&page="

# 定义获取单页PDF链接的函数
get_page_pdf_urls <- function(page_num) {
  page_url <- paste0(base_url, page_num)
  page <- read_html(page_url)
  
  page %>% 
    html_elements("a[href$='.pdf']") %>%  # 更精准匹配PDF链接
    html_attr("href") %>% 
    str_remove("\\?.*$") %>%  # 移除URL中?及之后的查询参数
    str_replace("^/", "https://www.ssoar.info/")  # 补全相对URL为绝对URL
}

# 获取所有分页的PDF链接(1200个文件需要12页)
all_pdf_urls <- map(1:12, get_page_pdf_urls) %>% flatten_chr()

# 生成合法的唯一文件名
pdf_filenames <- all_pdf_urls %>% 
  basename() %>% 
  # 处理可能的重复文件名,添加序号后缀
  make.unique(sep = "_")

# 定义带错误处理的下载函数
safe_download <- possibly(function(url, filename) {
  download.file(url, filename, mode = "wb", quiet = TRUE)
}, otherwise = NULL)

# 批量下载
walk2(all_pdf_urls, pdf_filenames, safe_download)

# 查看已下载的PDF文件
dir(pattern = "\\.pdf")

3. 关键改进点

  • 清理文件名:用str_remove("\\?.*$")删掉URL中的查询参数,确保文件名合法
  • 分页遍历:通过base_url拼接page参数,遍历1-12页获取全部链接
  • 补全绝对URL:原页面的PDF链接是相对路径,用str_replace补全为完整URL
  • 错误处理:possibly()函数让单个下载失败时不中断整个批量任务
  • 避免覆盖:make.unique()给重复文件名添加序号后缀,防止文件被覆盖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:25:09