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

使用rvest多页爬取时规避404错误的技术方案问询

解决方法

你遇到的问题是因为tryCatch返回了字符串"error 404",但后续代码仍尝试对这个字符串执行XML相关操作,自然会触发类型不匹配的错误。要跳过无效页面,只需要让无效URL对应的函数返回NULL,bind_rows会自动忽略这些空值。

方案1:用tryCatch包裹整个页面处理逻辑

修改getPageTable函数,把所有操作都放在tryCatch块内,遇到错误时直接返回NULL:

getPageTable <- function(url) {
  tryCatch({
    # 原有的页面读取和处理逻辑
    page <- read_html(url)
    
    gamedate <- page %>% html_element("div.scorebox_meta div") %>% html_text2()
    gameInfo <- page %>% html_elements("div.box h1") %>% html_text()
    headings <- page %>% html_elements("div.section_wrapper") %>% html_element("h2") %>% html_text()
    
    quarters <- grep("Q[1|2|3|4]", headings)
    tables <- page %>% html_elements("div.section_wrapper") %>% html_element("table") 
    
    headings <- headings[quarters]
    tables <- tables[quarters] %>% html_table(header=FALSE)
    
    tables <- lapply(1:length(tables), function(i) {
      names(tables[[i]]) <- tables[[i]][2,]
      tables[[i]] <- tables[[i]][-c(1:2),]  
      tables[[i]]$gamedate <- gamedate
      tables[[i]]$team <- headings[i]
      tables[[i]]$title <- gameInfo
      tables[[i]]
    })
    
    df <- bind_rows(tables)
    df <- df %>% filter("Starters" != "Reserves"  | "Starters" != "Team Totals" )
    df
  }, error = function(e) {
    # 可选:输出错误提示,方便排查
    message(paste("无法处理URL:", url, "错误信息:", e$message))
    NULL
  })
}

当URL无效时,函数返回NULL,后续lapply生成的列表里的空值会被bind_rows自动跳过,最终只保留有效页面的数据。

方案2:先检查HTTP状态码(更高效)

如果不想等到加载页面时才发现错误,可以先发送HEAD请求检查URL的有效性,避免无效的页面加载:

首先加载httr包:

library(httr)

然后修改getPageTable函数:

getPageTable <- function(url) {
  # 先检查HTTP状态码,仅处理状态码为200的有效页面
  resp <- HEAD(url)
  if (status_code(resp) != 200) {
    message(paste("URL不存在或无法访问:", url))
    return(NULL)
  }
  
  # 后续原有的页面处理逻辑
  page <- read_html(url)
  
  gamedate <- page %>% html_element("div.scorebox_meta div") %>% html_text2()
  gameInfo <- page %>% html_elements("div.box h1") %>% html_text()
  headings <- page %>% html_elements("div.section_wrapper") %>% html_element("h2") %>% html_text()
  
  quarters <- grep("Q[1|2|3|4]", headings)
  tables <- page %>% html_elements("div.section_wrapper") %>% html_element("table") 
  
  headings <- headings[quarters]
  tables <- tables[quarters] %>% html_table(header=FALSE)
  
  tables <- lapply(1:length(tables), function(i) {
    names(tables[[i]]) <- tables[[i]][2,]
    tables[[i]] <- tables[[i]][-c(1:2),]  
    tables[[i]]$gamedate <- gamedate
    tables[[i]]$team <- headings[i]
    tables[[i]]$title <- gameInfo
    tables[[i]]
  })
  
  df <- bind_rows(tables)
  df <- df %>% filter("Starters" != "Reserves"  | "Starters" != "Team Totals" )
  df
}

这种方法提前过滤无效URL,减少不必要的网络请求,效率更高。

最终效果

使用任意一种方案后,运行你的测试代码:

month <- c('02')
year <- c('2024')
day <- c('210','220','270','280')   
team <- c('CHI')

dates <- expand.grid(team = team, year = year, month = month, day = day)

urls <- dates |>
  mutate( url = make_url(team, year, month, day),
          team = team,
          date = paste(year, month, gsub('.{1}$', '', day), sep = '-'),
          .keep = 'unused'
        )

dfs <- lapply(urls$url, getPageTable)
finalResult <- bind_rows(dfs)
finalResult <- finalResult %>% separate("team", into=c("team", "quarter"), " \\(")
finalResult$quarter <- sub("\\)", "", finalResult$quarter)

代码会自动跳过202402210CHI.html这个无效页面,只返回另外三个有效页面的数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:57:38