R语言爬取赛事网站:如何提取图标文本并生成含弃权标识的数据框
BJJ赛事数据爬取问题解决
问题说明
要爬取某BJJ赛事系统存档页面的全部赛事数据,部分选手姓名旁的图标表示其因“未到场”弃权,目标是生成包含所有选手并标注弃权人员的数据框,但遇到两个问题:
- 尝试在姓名旁添加弃权标识时,报错
cannot coerce class "xml_nodeset" to a data.frame - 仅提取图标文本时得到空数据框
用户原代码:
library(rvest); library(tidyverse) html = read_html('https://web.archive.org/web/20220913034642/https://www.bjjcompsystem.com/tournaments/1869/categories/2053162') dq = data.frame(winner = html %>% html_nodes('.match-card__competitor--red') %>% html_text(trim = TRUE), opponent = html %>% html_nodes('hr+ .match-card__competitor'), dq = html %>% html_nodes('.match-card__disqualification') %>% html_text())
问题原因
- 第一个错误:
opponent列直接保留了html_nodes返回的xml_nodeset对象,没有转换成文本字符串,而data.frame无法直接存储这种对象,因此报错。 - 空数据框问题:
.match-card__disqualification这个CSS选择器无法单独定位到有效内容,弃权提示实际嵌套在选手节点的子元素中,单独调用找不到对应文本。
修正后的代码
通过遍历每个比赛卡片,分别提取单场赛事的选手信息和弃权状态:
library(rvest); library(tidyverse) # 读取目标页面 html <- read_html('https://web.archive.org/web/20220913034642/https://www.bjjcompsystem.com/tournaments/1869/categories/2053162') # 获取所有独立的比赛卡片节点 match_cards <- html %>% html_nodes('.match-card') # 遍历卡片提取数据并合并成数据框 tournament_data <- map_dfr(match_cards, function(card) { # 处理红方(获胜方)信息 red_competitor <- card %>% html_node('.match-card__competitor--red') red_name <- red_competitor %>% html_text(trim = TRUE) # 判断红方是否弃权 red_dq <- ifelse(!is.na(red_competitor %>% html_node('.match-card__disqualification')), "未到场弃权", "") # 处理蓝方(对手)信息 blue_competitor <- card %>% html_node('.match-card__competitor--blue') blue_name <- blue_competitor %>% html_text(trim = TRUE) # 判断蓝方是否弃权 blue_dq <- ifelse(!is.na(blue_competitor %>% html_node('.match-card__disqualification')), "未到场弃权", "") # 返回单场赛事的数据行 tibble( winner = red_name, winner_dq_status = red_dq, opponent = blue_name, opponent_dq_status = blue_dq ) }) # 查看最终结果 print(tournament_data)
代码说明
- 先定位所有
match-card节点,确保处理的是每一场独立赛事 - 对每个选手节点,先提取姓名文本,再检查是否存在弃权标识子节点,存在则标注弃权状态,否则留空
- 使用
map_dfr自动将单场数据合并成完整数据框,避免了类型不匹配的问题
内容的提问来源于stack exchange,提问作者bandcar
相关产品推荐
相关产品推荐

