如何用rvest按region/mrc/reseau层级提取指定网站表格数据?
提取魁北克饮用水分布数据的层级关系
网页的结构是Region表格后紧跟所属的MRC表格,每个MRC表格后再紧跟对应的Reseau表格,直到下一个Region表格出现。我们可以通过遍历所有Region节点,依次抓取其后续关联的MRC和Reseau数据,最终合并成包含层级的单表。
实现代码
library(rvest) library(dplyr) library(purrr) # 读取目标页面 url <- "https://www.environnement.gouv.qc.ca/eau/potable/distribution/resultats.asp" page <- read_html(url) # 获取所有带ID的表格节点(region/mrc/reseau) all_tables <- page %>% html_elements("table[id]") # 初始化结果列表 result_list <- list() # 遍历每个region表格 i <- 1 while (i <= length(all_tables)) { current_table <- all_tables[i] table_id <- current_table %>% html_attr("id") # 处理region表格 if (table_id == "region") { region_name <- current_table %>% html_element("td b") %>% html_text(trim = TRUE) i <- i + 1 # 收集当前region下的所有mrc和对应的reseau while (i <= length(all_tables)) { next_table <- all_tables[i] next_id <- next_table %>% html_attr("id") # 遇到新的region就停止当前region的处理 if (next_id == "region") break # 处理mrc表格 if (next_id == "mrc") { mrc_name <- next_table %>% html_element("td b") %>% html_text(trim = TRUE) i <- i + 1 # 处理对应的reseau表格 if (i <= length(all_tables) && (all_tables[i] %>% html_attr("id") == "reseau")) { reseau_df <- next_table %>% html_table(fill = TRUE) %>% slice(-1) %>% # 移除表头行 rename(Reseau = 1, Adresse = 2, Code_postal = 3, Municipalite = 4) %>% mutate(Region = region_name, MRC = mrc_name) %>% select(Region, MRC, everything()) result_list <- c(result_list, list(reseau_df)) i <- i + 1 } } else { # 意外情况,跳过非预期表格 i <- i + 1 } } } else { i <- i + 1 } } # 合并所有数据框 final_df <- bind_rows(result_list)
代码说明
- 先抓取页面中所有带ID的表格节点,按页面原有顺序排列;
- 外层循环遍历每个Region表格,记录当前Region名称后,进入内层循环处理其下属的MRC和Reseau;
- 内层循环中,遇到MRC表格时记录名称,紧接着处理对应的Reseau表格,为每条Reseau数据添加Region和MRC字段;
- 所有子数据框存入列表后,用
bind_rows合并为最终的层级数据表。
内容的提问来源于stack exchange,提问作者M. Beausoleil
相关产品推荐
相关产品推荐

