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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 14:40:33