使用Rvest爬取网站模态框生成图片遇阻求助
解决动态图片批量下载问题
你的问题核心在于:点击.button--veracta1按钮后,图片是通过JavaScript异步加载的,rvest只能抓取页面初始的静态HTML,无法获取动态生成的图片资源。下面提供两种可行的解决思路:
方法一:用RSelenium模拟浏览器操作
这种方法模拟真实用户的操作流程,适合不太熟悉抓API接口的场景,直观易上手。
代码实现:
# 首次运行需安装依赖包 install.packages(c("RSelenium", "rvest", "tidyverse")) library(RSelenium) library(rvest) library(tidyverse) # 启动Chrome浏览器驱动(需确保Chrome浏览器与ChromeDriver版本匹配) driver <- rsDriver(browser = "chrome", port = 4567L) remDr <- driver[["client"]] # 创建图片存储文件夹 if (!dir.exists("cas_images")) dir.create("cas_images") # 遍历所有目标页面 for (i in 1:24585) { tryCatch({ page_url <- paste0("https://trep.gt/#!/tc1/CAS/e0/m1/1?casId=M", i) cat("正在处理第", i, "页:", page_url, "\n") # 打开目标页面 remDr$navigate(page_url) Sys.sleep(1) # 等待页面基础内容加载 # 点击按钮触发图片加载 view_button <- remDr$findElement(using = "css selector", value = ".button--veracta1") view_button$clickElement() Sys.sleep(2) # 等待模态框及图片加载完成 # 提取图片地址(需根据实际页面结构调整选择器,比如.modal-content img) img_elem <- remDr$findElement(using = "css selector", value = ".modal img") img_src <- img_elem$getElementAttribute("src")[[1]] # 下载图片到本地 download.file(img_src, destfile = paste0("cas_images/M", i, ".jpg"), mode = "wb") # 关闭模态框,避免影响下一次操作 close_btn <- remDr$findElement(using = "css selector", value = ".modal .close") close_btn$clickElement() Sys.sleep(0.5) }, error = function(e) { cat("第", i, "页处理出错:", e$message, "\n") }) } # 关闭浏览器及驱动 remDr$close() driver$server$stop()
方法二:直接抓取API接口(效率更高)
如果能定位到按钮点击后触发的API请求,直接请求接口获取图片会比模拟浏览器快很多,步骤如下:
- 打开浏览器F12开发者工具,切换至Network标签
- 点击
.button--veracta1按钮,观察新出现的请求,找到返回图片资源的接口 - 复制该接口URL,分析请求参数(通常包含
casId=Mxxx)
代码示例(需替换为实际找到的API地址):
library(httr) library(tidyverse) # 创建图片存储文件夹 if (!dir.exists("cas_images")) dir.create("cas_images") # 遍历所有目标ID for (i in 1:24585) { tryCatch({ cas_id <- paste0("M", i) cat("正在处理", cas_id, "\n") # 替换为你找到的真实API接口地址 api_url <- paste0("https://trep.gt/api/cas/getImage?casId=", cas_id) # 请求并保存图片 img_response <- GET(api_url) writeBin(content(img_response, "raw"), paste0("cas_images/", cas_id, ".jpg")) Sys.sleep(0.3) # 控制请求频率,避免触发反爬机制 }, error = function(e) { cat(cas_id, "处理失败:", e$message, "\n") }) }
注意事项:
- 使用RSelenium时,ChromeDriver版本必须与本地Chrome浏览器版本一致,否则会启动失败
- 两种方法都加入了
tryCatch捕获错误,避免单个页面出错导致整个循环中断 - 不要将
Sys.sleep的时间设置过短,防止被网站判定为恶意爬虫
内容的提问来源于stack exchange,提问作者Luis Alburez
相关产品推荐
相关产品推荐

