使用RSelenium爬取动态列表时循环失效问题
问题排查与代码修正
你的循环失效无法获取所有法案描述的核心问题有以下几点,对应的修正方案如下:
核心问题分析
- 静态变量复用:你在循环外提前定义了
ementa变量,循环内直接赋值descrição <- ementa,导致每次循环都使用第一次测试的法案描述,而非当前页面的内容。 - 结果未存储:循环中每次覆盖
descrição变量,没有将每个链接的描述保存到集合中,最终只能保留最后一次(或始终相同)的内容。 - 脆弱的XPath定位:使用绝对路径
/html/body/main/div[4]/div/div[2]/div[1]定位元素,页面结构稍有变化就会失效。 - 时间等待不可靠:固定的
Sys.sleep(1)无法适应不同页面的加载速度,可能在元素未加载完成时就尝试获取内容。
修正后的完整代码
# 加载所需包 library(RSelenium) library(tidyverse) library(netstat) # 初始化Selenium驱动 remote_driver <- rsDriver(browser = 'firefox', verbose = FALSE, port = free_port(), chromever = NULL) remDr <- remote_driver$client remDr$open() # 导航到目标页面 main_url <- 'https://www.almg.gov.br/atividade-parlamentar/projetos-de-lei/texto/?tipo=PL&num=173&ano=2023' remDr$navigate(main_url) # 获取所有法案链接 identificação <- remDr$findElements(using = "css", ".js_interpretarLinksREADY") link_lei <- lapply(identificação, function(x) { x$getElementAttribute('href') %>% unlist() }) %>% flatten_chr() # 初始化存储结果的列表 ementas <- list() # 循环遍历前3个链接(可根据需求调整范围) for (i in seq_along(link_lei[1:3])) { t_url <- link_lei[i] remDr$navigate(t_url) # 显式等待法案描述元素加载(超时10秒) remDr$waitForElement(using = "css", value = ".ementa", timeout = 10000) # 获取当前页面的法案描述 current_ementa <- remDr$findElement(using = "css", value = ".ementa")$getElementText() %>% unlist() # 将结果存入列表 ementas[[i]] <- current_ementa # 返回上一页(比重新导航更高效) remDr$goBack() Sys.sleep(0.5) # 短时间等待页面恢复 } # 将结果转换为数据框以便查看和处理 ementas_df <- data.frame( 法案链接 = link_lei[1:3], 法案描述 = unlist(ementas) ) # 查看结果 print(ementas_df) # 关闭Selenium驱动 remDr$close() remote_driver$server$stop()
关键修正点说明
- 动态获取内容:在循环内每次导航到新链接后,重新定位并获取当前页面的法案描述,确保内容对应正确链接。
- 结果持久化:使用列表
ementas存储每个链接的描述,避免数据被覆盖。 - 健壮的元素定位:使用CSS选择器
.ementa替代绝对XPath,该选择器基于元素的类名,稳定性更强。 - 显式等待:
waitForElement确保元素加载完成后再进行操作,避免因页面加载慢导致的错误。 - 高效返回:使用
remDr$goBack()回到上一页,比重新导航到主页面更节省时间。
额外建议
- 可以添加
tryCatch块处理个别链接加载失败的情况,避免整个循环中断。 - 若需要爬取大量链接,可适当调整等待时间,或使用无头浏览器提升效率。
内容的提问来源于stack exchange,提问作者Fernanda Arraes
相关产品推荐
相关产品推荐

