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)
代码说明
- 空模板数据框:提前定义所有可能出现的列和对应类型,确保空表格/错误链接返回的结果结构完全匹配正常表格,从根源避免合并时的列不兼容问题。
- safely函数:包装爬取逻辑,即使单个链接爬取失败(比如网页不存在、表格缺失),也会返回错误信息而非中断整个流程,同时返回空模板保证结构一致。
- 列对齐处理:用
select(names(empty_template))强制对齐列顺序和数量,缺失的列自动用NA填充,进一步确保合并时的兼容性。 - %||%运算符:是
purrr包的语法,意思是如果左边的值为NULL,就用右边的默认值,避免因列不存在导致的报错。
这样修改后,无论遇到空表格还是爬取错误,都能保证所有返回的表格结构一致,unnest时不会出现合并错误,同时整个爬取流程不会因为单个链接失败而中断,效率更高。
内容的提问来源于stack exchange,提问作者DonnyDolio
相关产品推荐
相关产品推荐

