基于RSelenium的医院URL爬取:适配单/多页场景问题求助
适配单页/多页的医院Profile URL爬虫修改
问题背景
爬取美国各州医院Profile URL,目标页面为JS动态渲染的搜索结果页(如https://guide.prod.iam.aha.org/guide/searchResults?query=Alabama),结果分两种场景:
- 多页:存在分页导航,点击“Next”翻页,最后一页的
pagination-next标签会添加disabled类 - 单页:无分页导航
现有代码仅支持多页场景,单页时因找不到分页元素报错,需修改代码兼容两种情况。
原代码问题
原代码中使用findElement查找分页元素,单页场景下该元素不存在,直接抛出错误导致程序终止。
修改后的代码
library(tidyverse) library(rvest) library(RSelenium) library(wdman) library(netstat) # 初始化Selenium驱动(注意chromever需匹配本地Chrome版本) remote_driver <- rsDriver(browser = 'chrome', chromever = "116.0.5845.98", verbose = F, port = free_port()) remDr <- remote_driver$client collect_hospital_urls <- function(state_url){ remDr$navigate(state_url) preferred_class <- "disabled" all_profile_urls <- list() while (TRUE) { # 收集当前页所有医院Profile链接 profile_tags <- remDr$findElements(using = "css", value = "a[_ngcontent-c10]") profile_href_attributes <- sapply(profile_tags, function(tag) { tag$getElementAttribute("href")[[1]] }) all_profile_urls <- append(all_profile_urls, profile_href_attributes) # 查找分页导航的next元素(用findElements避免找不到时报错) li_pagination_next <- remDr$findElements(using = "class name", "pagination-next") # 情况1:没有分页元素,说明是单页,直接退出循环 if(length(li_pagination_next) == 0){ print("当前为单页结果,已收集所有链接") break } # 情况2:存在分页元素,判断是否为最后一页 li_classes <- unlist(li_pagination_next[[1]]$getElementAttribute("class")) %>% str_split("\\s+", simplify = T) %>% as.character() if(preferred_class %in% li_classes){ print("已到最后一页,停止翻页") break } else { # 点击下一页并等待加载 next_button <- remDr$findElement(using = 'link text', 'Next') next_button$clickElement() print("已跳转至下一页") Sys.sleep(2) } } # 去重并返回结果(避免重复链接) all_profile_urls <- all_profile_urls %>% unlist() %>% unique() return(all_profile_urls) } # 调用示例(替换为目标州的URL) state_url <- "https://guide.prod.iam.aha.org/guide/searchResults?query=Alabama" x <- collect_hospital_urls(state_url) # 用完后关闭驱动 remDr$close() remote_driver$server$stop()
关键修改点
- 用
findElements替代findElement:查找分页元素时,findElements在元素不存在时返回空列表而非报错,避免单页场景崩溃 - 添加单页判断逻辑:检查分页元素的长度,为0时直接退出循环
- 增加结果去重:避免翻页过程中可能出现的重复链接
- 补充资源释放:添加驱动关闭代码,避免资源占用
内容的提问来源于stack exchange,提问作者JustB
相关产品推荐
相关产品推荐

