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

R中download.file()返回403 Forbidden错误,网站加验证后代码失效求解决

网站新增用户验证后的PDF下载解决方案

针对你遇到的网站新增用户验证导致原R下载代码失效的问题,给你几个可行的解决方向:

1. 模拟带会话的HTTP请求(推荐用httr2包)

普通的download.file无法维持会话状态,而网站验证通常依赖Cookie或会话标识。用httr2可以先建立会话,通过验证后再发起下载请求:

library(tidyverse)
library(rvest)
library(httr2)

# 初始化会话,获取页面Cookie
session <- request("https://burnsville.civicweb.net/filepro/documents/25657/") %>%
  req_perform()

# 解析页面获取文件列表(和你原来的逻辑一致)
page <- session %>% resp_body_html()
df <- tibble(
  names1 = page %>%
    html_nodes(".document-link") %>%
    html_text2() %>%
    str_remove_all("\\r") %>%
    str_squish(),
  links = page %>%
    html_nodes(".document-link") %>%
    html_attr("href") %>%
    paste0("https://burnsville.civicweb.net", .)
)

# 循环下载,复用会话
walk2(df$links, df$names1, function(link, name) {
  tryCatch({
    request(link) %>%
      req_headers(
        "User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
        "Referer" = "https://burnsville.civicweb.net/filepro/documents/25657/"
      ) %>%
      req_cookies(resp_cookies(session)) %>% # 复用会话Cookie
      req_perform(path = paste0(name, ".pdf"))
  }, error = function(e) {
    message(paste("下载失败:", name, "错误信息:", e$message))
  })
})

2. 使用无头浏览器处理交互验证

如果网站需要点击同意按钮、输入简单图形验证码等交互操作,用RSelenium可以模拟真实浏览器行为(需先安装对应浏览器驱动,比如ChromeDriver):

library(RSelenium)
library(tidyverse)
library(rvest)

# 启动无头Chrome
driver <- rsDriver(browser = "chrome", chromever = "latest", extraCapabilities = list(
  chromeOptions = list(args = list("--headless=new"))
))
remDr <- driver[["client"]]

# 打开目标页面,处理验证(根据实际页面调整选择器,比如点击同意按钮)
remDr$navigate("https://burnsville.civicweb.net/filepro/documents/25657/")
# 示例:若有同意按钮,取消注释下面一行
# remDr$findElement(using = "css selector", value = ".btn-accept")$clickElement()

# 获取页面源码解析文件列表
page_source <- remDr$getPageSource()[[1]] %>% read_html()
df <- tibble(
  names1 = page_source %>%
    html_nodes(".document-link") %>%
    html_text2() %>%
    str_remove_all("\\r") %>%
    str_squish(),
  links = page_source %>%
    html_nodes(".document-link") %>%
    html_attr("href") %>%
    paste0("https://burnsville.civicweb.net", .)
)

# 循环下载,复用浏览器会话Cookie
walk2(df$links, df$names1, function(link, name) {
  tryCatch({
    request(link) %>%
      req_cookies(remDr$getAllCookies() %>% map_dfr(~list(name = .$name, value = .$value))) %>%
      req_perform(path = paste0(name, ".pdf"))
    Sys.sleep(1) # 避免请求过于频繁
  }, error = function(e) {
    message(paste("下载失败:", name, "错误信息:", e$message))
  })
})

# 关闭驱动
remDr$close()
driver$server$stop()

3. 手动提取验证后的Cookie

如果验证是一次性的(比如登录后Cookie有效期较长),可以手动在浏览器中完成验证,再复制Cookie到代码中:

  • 打开浏览器开发者工具(F12),切换到「网络」标签
  • 完成验证后刷新页面,找到任意请求的Cookie内容
  • 将Cookie添加到请求头,用httr2发起下载请求

另外,你的原代码存在两个小问题:

  • map调用错误直接使用df$links和df$names1,应该用walk2配对链接与文件名
  • for循环里的url变量未定义,需替换为循环变量i

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 08:03:01