使用RSelenium关闭特定弹窗并下载PDF文件的技术求助
无法从Demokratischer Widerstand网站获取并下载PDF文件
问题描述
网站更新后,原有R脚本无法正常工作,存在两个核心问题:
- 原提取PDF文件URL的代码失效,无法获取到文档链接
- 即使拿到URL,手动点击文档会弹出新窗口(需通过CSS选择器
.v-btn__content关闭),导致原下载逻辑可能无法运行
网站地址:https://demokratischerwiderstand.de/
原R脚本:
library(tidyverse) library(RSelenium) library(rvest) # Set up firefox profile and specifiy download options, navigate to url url <- "https://demokratischerwiderstand.de/" pdfprof <- makeFirefoxProfile(list( "pdfjs.disabled"=TRUE, "plugin.scan.plid.all"=FALSE, "plugin.scan.Acrobat" = "99.0", "browser.helperApps.neverAsk.saveToDisk"='application/pdf')) mydriver <- rsDriver(browser=c("firefox"), port=4444L, extraCapabilities=pdfprof, chromever = NULL) remDr <- mydriver[['client']] remDr$navigate(url) # Close popup window remDr$findElement(using = 'css', value = '.mdi-close')$clickElement() # Scroll down i times, waiting for the page to load at each time (to display all documents) for(i in 1:50){ remDr$executeScript(paste("scroll(0,",i*500,");")) Sys.sleep(2) } # SO FAR SO GOOD... # PROBLEM 1: The code below doesn't give me the URLs to the documents anymore remDr$getPageSource() %>% unlist() %>% read_html() %>% html_nodes("a") %>% html_attr("href") %>% str_subset("\\.pdf") -> dw_pdfs # PROBLEM 2: Even if I had the document URLs, this would probably no longer work, because every time I manually click on a document, another window pops up (would probably need to be closed each time using CSS = ".v-btn__content"). for(i in seq_along(dw_pdfs)) { download.file(dw_pdfs[i], here::here("downloaded_pdfs", paste0("widerstand_", i*-1+length(dw_pdfs)+1, ".pdf")), mode="wb") }
解决方案
解决问题1:提取有效的PDF URL
网站更新后,PDF链接不再直接暴露在<a>标签的href属性中,需针对新的页面结构调整提取逻辑:
方案1:从元素属性直接提取
检查页面后,PDF链接可能存储在文档按钮的data-href或类似自定义属性中,可通过以下代码提取:
# 替换原提取URL的代码 dw_pdfs <- remDr$getPageSource() %>% unlist() %>% read_html() %>% # 根据实际页面结构调整选择器,定位包含PDF链接的按钮 html_nodes(".document-item .v-btn") %>% html_attr("data-href") %>% # 过滤PDF格式链接 str_subset("\\.pdf") # 补全相对路径为完整URL dw_pdfs <- ifelse(str_detect(dw_pdfs, "^http"), dw_pdfs, paste0("https://demokratischerwiderstand.de", dw_pdfs))
方案2:模拟点击弹窗获取真实URL
若属性提取无效,可通过Selenium模拟点击,从弹窗窗口中获取PDF地址:
# 获取所有文档按钮元素 document_buttons <- remDr$findElements(using = "css", value = ".document-item .v-btn") dw_pdfs <- c() for(btn in document_buttons){ # 点击按钮打开弹窗 btn$clickElement() Sys.sleep(1) # 获取当前所有窗口句柄 handles <- remDr$getWindowHandles() # 切换到新打开的窗口 remDr$switchToWindow(handles[[2]]) # 获取PDF的真实URL pdf_url <- remDr$getCurrentUrl()[[1]] dw_pdfs <- c(dw_pdfs, pdf_url) # 关闭新窗口并切回原页面 remDr$closeWindow() remDr$switchToWindow(handles[[1]]) # 关闭弹窗(若需要) tryCatch({ remDr$findElement(using = "css", value = ".v-btn__content")$clickElement() Sys.sleep(1) }, error = function(e) NULL) }
解决问题2:自动处理弹窗并完成下载
优化浏览器配置+调整下载逻辑,实现无交互自动下载:
- 升级Firefox下载配置,指定目录并自动保存PDF:
pdfprof <- makeFirefoxProfile(list( "pdfjs.disabled" = TRUE, "plugin.scan.plid.all" = FALSE, "plugin.scan.Acrobat" = "99.0", "browser.helperApps.neverAsk.saveToDisk" = "application/pdf", "browser.download.dir" = here::here("downloaded_pdfs"), # 指定下载目录 "browser.download.folderList" = 2L, # 使用自定义下载目录 "browser.download.manager.showWhenStarting" = FALSE # 隐藏下载管理器弹窗 ))
- 使用获取到的URL批量下载:
# 确保下载目录存在 dir.create(here::here("downloaded_pdfs"), showWarnings = FALSE) # 批量下载PDF,加入异常处理避免中断 for(i in seq_along(dw_pdfs)) { tryCatch({ download.file(dw_pdfs[i], here::here("downloaded_pdfs", paste0("widerstand_", i, ".pdf")), mode = "wb", quiet = TRUE) cat("已完成下载:", dw_pdfs[i], "\n") }, error = function(e) { cat("下载失败:", dw_pdfs[i], "错误信息:", e$message, "\n") }) }
注意事项
- 页面元素选择器可能随网站更新变化,需定期检查页面结构调整CSS选择器
- 用显式等待(
remDr$waitForElement)替代固定Sys.sleep,可提升脚本稳定性 - 大量下载时需控制请求间隔,避免触发网站反爬机制
内容的提问来源于stack exchange,提问作者Dr. Fabian Habersack
相关产品推荐
相关产品推荐

