使用rvest爬取NHL薪资数据部分年份返回NULL的解决方法
解决rvest爬取NHL历年薪资数据的节点定位问题
我用rvest爬取Spotrac的NHL薪资数据时遇到问题,作为新手搞不清元素定位。需要获取2011-2022年的数据,但只有2020、2021、2022年能拿到,其余年份返回NULL。我的代码如下:
# vector of years years <- c(rep(2011:2022, by = 1)) # empty vector to store urls urls <- c() # create full urls for each year for (i in 1:12) { urls[i] <- paste0("https://www.spotrac.com/nhl/cap/", years[i], "/") } # empty list to store payroll tables payrolls <- list() # read in url and create a table for each year for (i in 1:length(urls)) { temp <- read_html(urls[i]) temp2 <- temp %>% html_nodes("table") payrolls[i] <- temp2 %>% html_table }
输出列表最后三个元素是正常格式,其余年份拿不到,猜测非目标年份的节点不是"table",用Selector Gadget提取节点没成功。
问题原因
Spotrac的页面结构在2020年前后有变化:
- 2020及之后的年份,薪资表格直接放在主页面的
<table>标签里; - 2011-2019年的薪资表格嵌入在iframe中,直接爬主页面的table会找不到数据。
修正代码
通过先提取iframe的链接,再爬取iframe内的表格,就能解决旧年份的数据获取问题:
library(rvest) # 生成2011-2022的年份序列 years <- 2011:2022 payrolls <- list() for (year in years) { # 构造主页面URL main_url <- paste0("https://www.spotrac.com/nhl/cap/", year, "/") main_page <- read_html(main_url) # 尝试提取iframe的src属性(旧年份表格在iframe里) iframe_src <- main_page %>% html_node("iframe#capview") %>% html_attr("src") # 分情况处理:有iframe则爬iframe页面,无则直接爬主页面 if (!is.na(iframe_src)) { # 拼接完整的iframe URL(原src是相对路径) iframe_url <- paste0("https://www.spotrac.com", iframe_src) table_data <- read_html(iframe_url) %>% html_node("table") %>% html_table() } else { table_data <- main_page %>% html_node("table") %>% html_table() } # 给表格添加年份标识,存入列表 table_data$year <- year payrolls[[as.character(year)]] <- table_data }
说明
- 代码通过
html_node("iframe#capview")定位到承载旧年份表格的iframe,提取其链接后再爬取内部表格; - 加入年份列方便后续对各年份数据进行合并或分析;
- 自动适配2020年前后两种页面结构,一次性获取所有年份的数据。
内容的提问来源于stack exchange,提问作者jacfein
相关产品推荐
相关产品推荐

