爬取欧洲大学学期学生统计网页并合并为DataFrame的问题
解决批量爬取欧洲大学学生统计数据并合并为DataFrame的问题
原代码的核心问题
- 循环范围错误:
for(i in length(all_url))只会让i取length(all_url)这单个数值,导致仅爬取最后一个URL的数据,而非全部URL。 - 未适配表格结构:单个页面返回的是「统计项-数值」的行式表格,直接合并会导致结构混乱,需转置为列格式并添加学期标识。
修正后的完整代码
先确保已加载所需依赖包:
library(rvest) library(dplyr)
然后执行批量爬取与数据合并:
# 初始化空列表存储处理后的数据框 result_list <- list() # 遍历所有URL,用seq_along生成正确的索引序列 for(i in seq_along(all_url)){ # 获取当前学期名称 term_name <- all_terms[i] # 爬取并格式化单页数据 page_data <- all_url[i] %>% read_html() %>% html_table() %>% # 提取页面中的第一个表格(假设每个页面仅含目标统计表格) .[[1]] %>% # 转置表格,将统计项转为列名、数值转为单行数据 t() %>% as.data.frame() %>% # 设置列名为转置后的第一行内容,随后移除该行 setNames(.[1, ]) %>% slice(-1) %>% # 添加学期列作为行标识 mutate(Semester = term_name) %>% # 调整列顺序,将学期列放在最前 select(Semester, everything()) # 将处理好的数据框加入列表 result_list[[i]] <- page_data } # 合并所有数据框为最终结果 final_df <- bind_rows(result_list)
代码关键说明
seq_along(all_url):生成从1到URL总数的连续索引,确保遍历每个页面。- 表格转置:将原行式的「统计项-数值」结构转为列式,满足「学期为行、统计项为列」的需求。
bind_rows():替代do.call(rbind, ...),更稳定地合并数据框,适配不同页面可能的列差异。
可选优化:添加错误处理
若担心部分URL访问失败导致循环中断,可加入tryCatch捕获错误:
page_data <- tryCatch({ all_url[i] %>% read_html() %>% html_table() %>% .[[1]] %>% t() %>% as.data.frame() %>% setNames(.[1, ]) %>% slice(-1) %>% mutate(Semester = term_name) %>% select(Semester, everything()) }, error = function(e){ warning(paste("爬取失败:", all_url[i], ",错误信息:", e$message)) return(NULL) })
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

