使用Rvest批量抓取fbref多URL数据的技术求助
批量抓取fbref五大联赛球员数据并合并
问题分析
你当前代码的核心问题是read_html()不支持直接传入URL向量,必须逐个处理每个URL;另外URL生成时的rep()和sort()是多余的,会导致重复URL。同时需要处理表格的表头合并问题,并为每个赛季数据添加赛季标识列。
修正后的代码
library(rvest) library(tidyverse) # 生成赛季年份对与赛季标识 year_pairs <- tibble( year1 = 2006:2021, year2 = 2007:2022 ) %>% mutate(season = paste0(year1, "-", year2)) # 生成对应赛季的URL列表 urls <- paste0("https://fbref.com/en/comps/Big5/", year_pairs$season, "/stats/players/", year_pairs$season, "-Big-5-European-Leagues-Stats") # 定义单赛季数据抓取函数 scrape_season_data <- function(url, season) { # 读取目标网页 page <- read_html(url) # 抓取标准统计表格(指定ID避免抓错) table <- page %>% html_nodes("table#stats_standard") %>% html_table(header = TRUE, fill = TRUE) %>% pluck(1) # 提取列表中的数据框 # 合并两行表头(fbref表格存在分层表头) names(table) <- paste(names(table), table[1, ], sep = "_") %>% str_remove_all("_NA") %>% str_replace_all(" ", "_") # 移除原表头行 table <- table[-1, ] # 添加赛季标识列 table <- table %>% mutate(Season = season, .before = 1) return(table) } # 批量处理所有赛季 all_seasons_data <- map2(urls, year_pairs$season, scrape_season_data) # 合并所有赛季数据 combined_data <- bind_rows(all_seasons_data) # 导出为CSV文件 write.csv(combined_data, "fbref_big5_players_2006-2022.csv", row.names = FALSE)
关键说明
- URL生成:直接用年份对生成对应赛季的URL,去掉多余的重复和排序操作,确保每个URL对应唯一赛季。
- 表格抓取:指定表格ID
#stats_standard精准定位目标表格,避免抓取页面上的其他无关表格;html_table()设置header=TRUE和fill=TRUE,适配fbref的合并表头和不规则列结构。 - 表头清理:将fbref的分层表头合并为一行有意义的列名,避免后续数据处理出现混乱。
- 批量处理:用
map2()同时遍历URL和赛季标识,一次性完成数据抓取与赛季列添加,比lapply()更高效关联赛季信息。 - 数据合并:用
bind_rows()自动合并所有赛季的数据框,结构一致的行会被正确整合。
内容的提问来源于stack exchange,提问作者Bob H
相关产品推荐
相关产品推荐

