You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何使用R爬取Fangraphs部分球员数据表格成功,其他表格却返回NULL?

为何使用R爬取Fangraphs部分球员数据表格成功,其他表格却返回NULL?

嘿,我来帮你排查这个问题!你遇到的情况其实很常见——这不是你的XPATH写错了,而是Fangraphs上的部分表格加载方式和你成功抓取的那些不一样。

问题根源:静态VS动态加载

你能成功抓取的Dashboard、Standard这类表格,是页面首次加载时就直接嵌入在静态HTML里的,所以read_html()能直接读到它们的代码。但像Fielding、Statcast - Bat Tracking这类标签对应的表格,是要等你点击标签切换时,才通过JavaScript动态注入到页面中的。

而read_html()只能获取页面刚加载时的静态内容,根本看不到这些后续才生成的表格节点,所以html_nodes()找不到对应元素,自然返回NULL啦。

两种解决方案

方案1:用浏览器自动化工具抓取动态内容(适合新手直观操作)

这种方法会模拟你手动操作浏览器的过程(比如点击标签),能完整获取动态加载的内容。推荐用playwright包(比传统的RSelenium更轻量易用):

首先安装依赖:

install.packages("playwright")
playwright::install_browsers() # 安装浏览器驱动

然后写代码模拟操作并抓取Fielding表格:

library(playwright)
library(purrr)
library(rvest)

# 启动无头浏览器(不会弹出可视化窗口)
pw <- chromium$launch(headless = TRUE)
page <- pw$new_page()

# 打开Basallo的球员页面
page$goto("https://www.fangraphs.com/players/samuel-basallo/28824/stats/batting")

# 点击Fielding标签(用文本匹配定位按钮)
page$click("text=Fielding")

# 等待表格加载完成(给JavaScript留渲染时间)
page$wait_for_selector("#fielding table")

# 读取完整的页面HTML(包含动态加载的内容)
html_content <- page$content()
url_read_html <- read_html(html_content)

# 抓取并提取表格
data_look <- url_read_html |> 
  html_nodes(css = "#fielding table") |> # 用CSS选择器比XPATH更稳定
  html_table() |>
  pluck(1)

# 关闭浏览器
pw$close()

方案2:直接抓取AJAX接口(更高效稳定)

如果你想批量抓取或者追求效率,直接抓Fangraphs加载表格的后台接口会更好——不用模拟浏览器,速度快,还不容易因为页面布局变化失效:

  1. 打开Chrome开发者工具(F12),切换到Network标签,勾选「XHR/Fetch」过滤项
  2. 点击页面上的Fielding标签,观察Network列表里新增的请求,找到返回表格数据的AJAX接口(通常是JSON格式)
  3. 复制这个接口的URL,用httr2直接请求并解析数据:

示例代码(请替换成你抓到的真实接口URL):

library(httr2)
library(jsonlite)

# 替换成你从Network面板抓到的真实接口地址
api_url <- "https://www.fangraphs.com/api/players/stats?playerid=28824&position=B&type=fielding&season=2024&leagueid=all"

# 请求接口并解析JSON数据
fielding_data <- request(api_url) |> 
  req_perform() |> 
  resp_body_json() |>
  pluck("data") |> # 根据接口返回的JSON结构调整提取路径
  as.data.frame()

这种方法的好处是,接口返回的是结构化数据,不用再清洗HTML表格,而且批量抓取时速度会比模拟浏览器快很多。

小提示

  • 尽量用CSS选择器(比如#fielding table)代替XPATH,因为页面布局变化时XPATH更容易失效
  • 如果要批量抓取多个球员,直接用AJAX接口会节省大量时间,模拟浏览器的话速度会慢很多

备注:内容来源于stack exchange,提问作者Buckaroo Banzai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 17:58:05