R语言rvest包html_elements提取重复分类值填充数据框方法
问题根源
你之前无法关联分类和赛事的核心原因是:该页面的层级分类(运动类型、国家、联赛)和具体赛事条目是同级兄弟节点,按从上到下的顺序排列在DOM树中,并非嵌套在分类节点内部。单独提取所有分类文本、所有赛事文本后,两个序列的索引没有稳定的对应关系,很容易错位。
实现方案
核心逻辑是按节点在页面中出现的顺序逐一遍历,维护当前层级的分类状态,遇到赛事条目时直接绑定当前状态值即可,步骤如下:
- 先提取赛事列表容器下所有相关节点(运动分类头、国家分类头、联赛分类头、具体赛事条目),保留节点在页面里的原始顺序
- 初始化三个变量分别存储当前遍历位置对应的运动类型、国家、联赛值,初始值设为缺失
- 按顺序遍历每个节点:如果是分类头节点,就更新对应分类变量的值;如果是具体赛事节点,就提取赛事本身的标题、比分、时长字段,和当前三个分类变量的值组合为一行记录存入结果集
- 所有节点遍历完成后,把结果集合并为最终数据框
参考实现代码
library(rvest) library(tidyverse) page <- read_html("https://www.supermatch.com.uy/live_recargar_menu/") # 按页面顺序提取所有分类节点、赛事节点 all_nodes <- page %>% html_elements(xpath = "//div[contains(@class,'contenedor_live')]/*[self::div[contains(@class,'deporte')] or self::div[contains(@class,'pais')] or self::div[contains(@class,'liga')] or self::div[contains(@class,'partido')]]") # 初始化状态变量和结果存储列表 current_sport <- NA_character_ current_country <- NA_character_ current_league <- NA_character_ result_list <- list() # 顺序遍历节点匹配层级关系 for (i in seq_along(all_nodes)) { node <- all_nodes[[i]] node_class <- html_attr(node, "class") # 遇到运动类型头,更新当前运动状态 if (str_detect(node_class, "deporte")) { current_sport <- html_text(node) %>% str_squish() next } # 遇到国家头,更新当前国家状态 if (str_detect(node_class, "pais")) { current_country <- html_text(node) %>% str_squish() next } # 遇到联赛头,更新当前联赛状态 if (str_detect(node_class, "liga")) { current_league <- html_text(node) %>% str_squish() next } # 遇到具体赛事,绑定当前层级状态+提取赛事字段 if (str_detect(node_class, "partido")) { match_row <- tibble( Tipo_deporte = current_sport, Pais = current_country, Nombre_competicion = current_league, Titulo = html_element(node, ".titulo") %>% html_text() %>% str_squish(), Marcador = html_element(node, ".marcador") %>% html_text() %>% str_squish(), Tiempo = html_element(node, xpath = "./*[contains(@class,'marcador')]/following-sibling::span[1]") %>% html_text() %>% str_squish() ) result_list <- append(result_list, list(match_row)) } } # 合并为最终结构化数据框 final_data <- bind_rows(result_list)
适配提示
- 如果实际页面的class命名和代码里的匹配规则有出入,直接调整节点class的判断逻辑即可,核心遍历逻辑不需要改动
- 这种顺序遍历+状态更新的方式容错率远高于按索引硬匹配,哪怕某个分类下的赛事数量临时增减,也不会出现分类和赛事错位的问题
- 如果碰到页面内容异步加载、静态请求拿不到全量节点的情况,可以先抓包拿到live数据的接口返回值再做解析,层级匹配的逻辑完全通用
内容的提问来源于stack exchange,提问作者Emiliano Barone
相关产品推荐
相关产品推荐

