R语言爬取NBA官网阵容进阶数据返回空表问题求解决方案
问题根因
你之前用到的静态爬取方法失效,核心原因是NBA stats站点采用客户端JavaScript异步渲染逻辑:
- 首次请求返回的HTML仅包含页面基础骨架,表格数据是后续JS调用后台接口加载完成后才动态渲染到页面上的,rvest等静态爬取工具只能拿到未填充数据的空HTML结构,所以提取不到表格
- 你直接请求页面URL返回的是HTML文本而非JSON格式的接口数据,所以解析JSON会报错
可行解决方案(R语言实现)
方案1:RSelenium模拟浏览器获取渲染后数据(兼容性强,无需分析接口)
该方案通过模拟真实浏览器访问页面,等待数据渲染完成后再提取内容,适配绝大多数动态渲染站点。
# 首次使用先安装依赖包 install.packages(c("RSelenium", "rvest", "dplyr")) library(RSelenium) library(rvest) library(dplyr) # 启动Chrome驱动(rsDriver会自动匹配对应版本的ChromeDriver,如有版本冲突可手动指定chromever参数) driver <- rsDriver(browser = "chrome", port = 4545L) remDr <- driver[["client"]] # 访问目标页面 target_url <- "https://www.nba.com/stats/lineups/advanced" remDr$navigate(target_url) # 等待页面数据加载完成,可根据网络情况调整等待时长 Sys.sleep(8) # 如果需要获取全部2000行数据,可在此处添加模拟点击切换每页显示条数、滚动加载的JS代码 # 示例:模拟点击选择每页显示2000行,可根据页面实际元素调整选择器 # remDr$findElement(using = "css", value = ".rows-per-page select option[value='2000']")$clickElement() # Sys.sleep(3) # 获取渲染后的完整页面源码 page_source <- remDr$getPageSource()[[1]] page_html <- read_html(page_source) # 提取表格数据 lineups_table <- page_html %>% html_nodes("table") %>% html_table() %>% .[[1]] # 关闭驱动释放资源 remDr$close() driver$server$stop() # 输出数据预览 head(lineups_table)
方案2:直接调用官方数据接口(性能更高,无需启动浏览器)
通过浏览器开发者工具的网络面板可抓取到表格数据对应的官方接口,直接请求接口即可拿到结构化数据,无需解析HTML。
library(httr) library(jsonlite) library(dplyr) # 构造请求头,模拟浏览器请求避免被站点拦截 req_headers <- c( `Accept` = "*/*", `Accept-Language` = "zh-CN,zh;q=0.9,en;q=0.8", `Host` = "stats.nba.com", `Origin` = "https://www.nba.com", `Referer` = "https://www.nba.com/", `User-Agent` = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" ) # 接口请求参数,可按需调整赛季、数据类型、返回行数等配置 req_params <- list( `LeagueID` = "00", `MeasureType` = "Advanced", `PerMode` = "Totals", `Season` = "2023-24", `SeasonType` = "Regular Season", `GroupQuantity` = "5", `PageNo` = "1", `RowsPerPage` = "2000" ) # 发送接口请求 res <- GET( url = "https://stats.nba.com/stats/leaguedashlineups", add_headers(.headers = req_headers), query = req_params ) # 解析JSON返回结果 res_json <- content(res, as = "text", encoding = "UTF-8") %>% fromJSON() # 转换为数据框,自动匹配表头 lineups_table <- as.data.frame(res_json$resultSets$rowSet[[1]]) colnames(lineups_table) <- res_json$resultSets$headers[[1]] # 输出数据预览 head(lineups_table)
注意事项
- 接口参数可根据你的数据需求调整,比如修改
Season参数获取对应赛季的数据,修改PerMode参数切换场均/累计统计维度 - 如果请求接口被拦截,可更换User-Agent参数、增加1-2秒的请求延迟即可解决
内容的提问来源于stack exchange,提问作者BLP92
相关产品推荐
相关产品推荐

