
本文详解如何用 rvest 正确抓取 html 表格:推荐优先使用 `html_table()` 自动解析,若手动定位需注意 css 选择器语法(如误加 `.` 导致匹配失败),并提供可直接运行的完整代码示例。
在使用 R 进行网页数据抓取时,初学者常因 CSS 选择器书写错误或忽略 HTML 结构特性而遭遇“空变量”问题——即 html_nodes() 返回零长度结果,最终生成的数据框全为空值。以抓取 Fortune 500 公司列表页 为例,该页面仅包含一个标准
元素,因此最稳健、简洁的方案是直接调用 rvest 内置的 html_table() 函数:library(tidyverse)
library(rvest)
url <- "https://www.php.cn/link/c5f5688aab21d00610e8cdeae7a56ebf"
page <- read_html(url)
# ✅ 推荐:一行提取整张表(自动处理表头、类型推断)
fortune500 <- page %>% html_table() %>% pluck(1) # pluck(1) 取第一个(也是唯一)表格
glimpse(fortune500)
该方法优势显著:
- 自动识别 和
,正确提取列名;
- 智能转换数值列(如 Rank 列自动为整型);
- 无需手动编写复杂 CSS 或 XPath,大幅降低出错概率。
若坚持使用节点级选择(例如需处理多层嵌套或非标准表格),则必须严格校验 CSS 选择器语法。原代码中 ".td:nth-child(1)" 的错误在于前缀 . —— 它表示“匹配 class='td' 的元素”,但目标实际是
文心快码
文心快码(Comate)是百度推出的一款AI辅助编程工具
下载
标签(HTML 标签名,非 class)。正确写法应为 "td:nth-child(1)"(无点号):# ⚠️ 修正后的手动提取(仅作教学参考)
rank <- page %>% html_nodes("td:nth-child(1)") %>% html_text(trim = TRUE)
company <- page %>% html_nodes("td:nth-child(2)") %>% html_text(trim = TRUE)
website <- page %>% html_nodes("td:nth-child(3)") %>% html_text(trim = TRUE) # 更清晰:直接选第3列,替代模糊的 "td~ td+ td"
fortune500_manual <- tibble(
Rank = as.integer(rank),
Company = company,
Website = website
)关键注意事项:
- 始终添加 trim = TRUE 参数(html_text() 默认不修剪首尾空白,易引入不可见换行符);
- 使用 tibble() 替代 data.frame(),避免因子自动转换等意外行为;
- 对数值列显式转换(如 as.integer()),防止后续分析出错;
- 抓取前建议先用 html_structure(page)(来自 rvest 1.0+)或浏览器开发者工具检查真实 DOM 结构——该页面中表格无 包裹,所有
| 直接位于 |
下,故 nth-child 定位完全可靠。最后提醒:目标网站未设置反爬机制,但生产环境中务必遵守 robots.txt、添加请求延迟(Sys.sleep(1)),并考虑使用 httr2 管理会话与 User-Agent。掌握 html_table() 这一“银弹”方法,可解决绝大多数静态表格抓取需求,让数据获取回归高效与可靠。
|