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

R语言网页爬取中如何跳过空表格?

解决网页爬取中空表格导致的DataFrame合并错误

你的问题核心是部分网页返回空表格或列结构不一致,导致unnest时无法合并列。以下是高效的解决思路和修改后的代码:

核心改进点

  • 提前定义统一结构的空模板数据框,确保空表格/错误链接返回的结果和正常表格列数、类型一致
  • 用safely包装爬取逻辑,捕获单个链接的爬取错误,避免整个流程中断
  • 强制统一关键列的类型,避免类型不兼容导致的合并失败

修改后的完整代码

library(rvest)
library(tidyverse)

# 生成爬取链接列表
df <- expand.grid(
  tournament_id = c("t060", "t475", "t045", "t021"),
  stat_id = c("02564", "101", "102", "336", "340"),
  year_id = c("2004", "2005", "2006")
) %>% 
  mutate(
    links = paste0(
      'https://www.pgatour.com/stats/stat.',
      stat_id,
      '.y',
      year_id,
      '.eon.',
      tournament_id,
      '.html'
    )
  ) %>% 
  as_tibble()

# 定义空模板数据框:包含所有可能的列,类型统一
empty_template <- tibble(
  rank_this_week = integer(),
  player_name = character(),
  avg = character(),
  gir_rank = character(),
  total_distance_feet = character(),
  tournament_id = character()
)

# 包装后的安全爬取函数
safe_get_info <- safely(function(link, tournament_id) {
  # 爬取网页并提取表格
  page <- read_html(link)
  tables <- html_table(page)
  
  # 检查表格是否存在且非空
  if (length(tables) < 2 || nrow(tables[[2]]) == 0) {
    return(empty_template %>% mutate(tournament_id = tournament_id))
  }
  
  # 处理正常表格
  data <- tables[[2]] %>%
    clean_names() %>% 
    select(-rank_last_week, .keep_all = TRUE) %>% 
    mutate(
      rank_this_week = as.integer(str_extract(rank_this_week, "\\d+")),
      tournament_id = tournament_id
    )
  
  # 统一列类型,不存在的列用NA填充
  data <- data %>%
    mutate(
      avg = as.character(avg %||% NA_character_),
      gir_rank = as.character(gir_rank %||% NA_character_),
      total_distance_feet = as.character(total_distance_feet %||% NA_character_)
    )
  
  # 对齐模板列,缺失的列用NA填充
  data <- data %>% select(names(empty_template))
  
  return(data)
})

# 批量爬取并合并数据
test101 <- df %>%
  mutate(
    # 调用安全爬取函数,返回结果和错误信息
    result = map2(links, tournament_id, safe_get_info),
    # 提取爬取结果(忽略错误)
    tables = map(result, "result"),
    # 过滤掉NULL结果(如果有的话)
    tables = map(tables, ~ .x %||% empty_template)
  ) %>%
  # 展开表格,此时所有表格结构一致,不会报错
  tidyr::unnest(tables) %>%
  # 移除临时的result列
  select(-result)

代码说明

  1. 空模板数据框:提前定义所有可能出现的列和对应类型,确保空表格/错误链接返回的结果结构完全匹配正常表格,从根源避免合并时的列不兼容问题。
  2. safely函数:包装爬取逻辑,即使单个链接爬取失败(比如网页不存在、表格缺失),也会返回错误信息而非中断整个流程,同时返回空模板保证结构一致。
  3. 列对齐处理:用select(names(empty_template))强制对齐列顺序和数量,缺失的列自动用NA填充,进一步确保合并时的兼容性。
  4. %||%运算符:是purrr包的语法,意思是如果左边的值为NULL,就用右边的默认值,避免因列不存在导致的报错。

这样修改后,无论遇到空表格还是爬取错误,都能保证所有返回的表格结构一致,unnest时不会出现合并错误,同时整个爬取流程不会因为单个链接失败而中断,效率更高。

内容的提问来源于stack exchange,提问作者DonnyDolio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 04:46:10