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

R语言批量爬取网页时遭遇解析错误与数据重复问题求助

R语言批量爬取网页时遭遇解析错误与数据重复问题求助

嗨,我来帮你捋捋问题出在哪,你遇到的解析错误和数据重复,大概率和会话管理混乱、页面加载等待逻辑不完善以及错误处理不到位有关,咱们一步步来解决:

问题根源拆解

  • 重复创建Chromote会话:你每次调用test(i)都新建一个ChromoteSession,这不仅浪费系统资源,还可能导致之前的会话没被正确销毁,残留的状态会干扰后续请求,进而返回重复或错误的数据。
  • 页面等待逻辑太弱:loadEventFired只等页面触发加载完成事件,但有些动态渲染的内容可能在这个事件之后才生成,这时候获取的HTML大概率不完整,解析JSON自然会出错,甚至返回之前的缓存内容。
  • tryCatch处理不完整:你的tryCatch没有定义错误处理分支,出错时可能默认返回最后一次成功的结果,或者把无效/重复值塞进列表,同时也没记录哪些i值出了问题,不利于后续补爬。

优化方案与改进代码

1. 复用Chromote会话

把会话创建移到循环外面,整个爬取过程只用一个会话,用完及时关闭,避免资源泄漏和状态残留。

2. 完善页面等待逻辑

用navigate的wait_ = TRUE确保页面加载完成,再加上短暂的休眠时间,避免请求过快触发网站反爬,也给动态内容留足渲染时间。

3. 增强错误处理

在tryCatch里明确错误分支,记录出错的i值,出错时不把无效数据加入列表,方便后续补爬。

4. 优化列表构建

预先初始化列表长度,用索引赋值的方式添加元素,比c(ma_liste, list(...))更高效,也能避免潜在的重复元素问题。

改进后的完整代码:

library(rvest)
library(chromote)
library(jsonlite)
library(dplyr)

# 改进test函数:接收已创建的会话作为参数,避免重复创建
test <- function(session, i) {
  # 导航到目标页面,等待页面完全加载
  session$Page$navigate(paste0("https://www.ecologie.gouv.fr/sru_api/api/towns/", i), wait_ = TRUE)
  
  # 短暂休眠,给动态内容留足渲染时间(可根据网站情况调整时长)
  Sys.sleep(0.8)
  
  # 获取页面完整HTML
  html <- session$Runtime$evaluate('document.documentElement.outerHTML')
  content <- read_html(html$result$value)
  data_json <- html_text(content)
  df <- fromJSON(data_json)
  
  return(df)
}

# 初始化单个Chromote会话
b <- ChromoteSession$new()

# 预先初始化列表,指定长度提升效率
n <- 100
ma_liste <- vector("list", length = n - 1) # i从2到n,共n-1个元素
error_indices <- c() # 记录出错的页面索引

for (i in 2:n) {
  tryCatch({
    # 用索引赋值,避免动态拼接列表的问题
    ma_liste[[i - 1]] <- test(b, i)
    cat("成功爬取第", i, "页\n")
  }, error = function(e) {
    cat("爬取第", i, "页出错:", e$message, "\n")
    error_indices <- c(error_indices, i)
  })
}

# 关闭会话,释放资源
b$close()

# 过滤列表中的空值(出错的位置)
ma_liste <- ma_liste[!sapply(ma_liste, is.null)]

# 合并为数据框
dataframe <- do.call(rbind, ma_liste)
dataframe <- as.data.frame(dataframe)

# 查看出错的索引,方便后续补爬
print("出错的页面索引:")
print(error_indices)

额外小建议

其实你爬的目标看起来是个JSON API接口,完全可以不用chromote模拟浏览器,直接用httr包请求接口,这样更稳定高效,也不会有页面渲染的问题:

library(httr)
library(jsonlite)

test_api <- function(i) {
  url <- paste0("https://www.ecologie.gouv.fr/sru_api/api/towns/", i)
  response <- GET(url)
  stop_for_status(response) # 请求出错时直接抛出错误
  df <- fromJSON(content(response, "text"))
  return(df)
}

# 后续的循环、错误处理逻辑和上面一致即可

备注:内容来源于stack exchange,提问作者Alexique

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 06:09:35