R语言网页爬取遇列表下标越界问题及表格处理需求
问题解决指南
1. 补全爬虫函数并加入错误处理
你的sebi_pm代码被截断了,先补全完整的请求逻辑,同时加上错误处理,避免单个投资组合经理的请求失败导致整个批量任务中断:
library(tidyverse) library(rvest) library(httr) url <- "https://www.sebi.gov.in/sebiweb/other/OtherAction.do?doPmr=yes" pm_id <- read_html(url) %>% html_elements('select[name="pmrId"].f_control option') %>% html_attr("value") %>% .[2:416] # 跳过第一个空选项 sebi_pm <- function(x) { tryCatch({ # 发送POST请求,指定2022年8月参数 resp <- POST(url, body = list( pmrId = x, year = "2022", month = "8", submit = "Submit" ), encode = "form") # 解析页面首个表格,按无表头读取(表单式表格通常无预设表头) table_data <- resp %>% read_html() %>% html_elements("table") %>% .[[1]] %>% html_table(header = FALSE) # 添加pm_id标识列,方便后续关联数据 table_data %>% mutate(pmr_id = x) }, error = function(e) { message(paste("处理pm_id", x, "时出错:", e$message)) tibble() # 出错时返回空数据框,不中断整个批量任务 }) }
2. 批量爬取并过滤无效数据
批量处理所有pm_id时,记得添加请求间隔避免被网站封禁,之后过滤掉无数据的结果:
# 批量爬取,每次请求间隔1秒降低封禁风险 pm_data_list <- lapply(pm_id, function(x) { Sys.sleep(1) sebi_pm(x) }) # 只保留有有效数据的结果 valid_data <- pm_data_list %>% keep(~nrow(.) > 0)
3. 表单式表格转规范DataFrame
对于首列是变量名、第二列是对应值的表单式表格,用tidyr::pivot_wider可以快速转换为规范宽表(每个投资组合经理一行,变量作为列):
# 先合并所有长格式数据 long_df <- bind_rows(valid_data) # 转换为规范宽表 wide_df <- long_df %>% pivot_wider( id_cols = pmr_id, names_from = V1, # 第一列是变量名 values_from = V2 # 第二列是变量对应的值 )
4. 解决"subscript out of bounds"错误
这个错误的核心原因是:部分pm_id请求后没有返回表格,导致html_elements("table")[[1]]试图从空列表中提取元素,触发下标越界。
修复后的函数用tryCatch捕获这类错误并返回空数据框,后续过滤掉空数据后,用bind_rows合并(比do.call(rbind, ...)更稳健,能自动处理列名不一致的情况),就不会再出现该错误。
内容的提问来源于stack exchange,提问作者mathplyr
相关产品推荐
相关产品推荐

