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

R语言rvest批量爬虫:如何用循环自动化实现多网页数据提取

报错原因

rvest::read_html() 单次调用仅支持传入长度为1的单条URL字符串,直接传入长度为100的URL向量必然触发Error: 'x' must be a string of length 1报错。批量抓取的核心逻辑是对URL向量做逐页迭代,单页执行读取、节点提取操作后,再统一合并所有结果。

推荐实现方案:purrr迭代写法

这种写法不需要手动管理循环索引和存储结构,自带容错、限速能力,代码更简洁:
首先加载依赖、提前定义你已经写好的自定义取数函数:

library(rvest)
library(purrr)
library(dplyr)

# 自定义间隔取数函数
nth_element <- function(vector, starting_position, n) {
  vector[seq(starting_position, length(vector), n)]
}

封装单页抓取逻辑,加入容错、限速机制,避免单页报错中断全流程,也避免高频请求被站点拦截:

# 单页抓取逻辑
scrape_single_page <- function(url) {
  # 随机停顿1-2秒,降低请求频率
  Sys.sleep(sample(1:2, 1))
  
  page <- read_html(url)
  page_text <- page %>%
    html_nodes("td") %>%
    html_text()
  target_val <- nth_element(page_text, 10, 5)
  
  # 返回带源URL的结果,方便后续溯源
  return(data.frame(
    source_url = url,
    target_content = target_val
  ))
}

# 给抓取函数加容错:单页抓取失败时记录错误,不中断整体流程
safe_scrape <- safely(scrape_single_page)
# 加全局限速
slow_safe_scrape <- slowly(safe_scrape, rate = rate_delay(pause = 1.5))

# 传入URL向量执行批量抓取
all_raw_res <- map(webpage_urls, slow_safe_scrape)

最后整合结果:

# 提取所有抓取成功的页面结果,合并为统一数据框
final_table <- map_dfr(all_raw_res, ~.x$result)

# 可选:提取抓取失败的页面及对应错误信息
failed_info <- keep(all_raw_res, ~!is.null(.x$error)) %>%
  map_chr(~.x$error$message)
failed_pages <- data.frame(
  source_url = webpage_urls[which(sapply(all_raw_res, ~!is.null(.x$error)))],
  error_msg = failed_info
)
备选方案:基础R for循环实现

不需要额外安装purrr包,逻辑更直白,适合R基础用户:

# 提前创建和URL数量等长的空列表存储结果,比逐行合并效率高
res_list <- vector("list", length = length(webpage_urls))

for (i in seq_along(webpage_urls)) {
  current_url <- webpage_urls[i]
  Sys.sleep(sample(1:2, 1))
  
  # 容错处理
  tryCatch({
    page <- read_html(current_url)
    page_text <- page %>%
      html_nodes("td") %>%
      html_text()
    target_val <- nth_element(page_text, 10, 5)
    
    res_list[[i]] <- data.frame(
      source_url = current_url,
      target_content = target_val
    )
    # 打印进度
    cat("已完成第", i, "页,剩余", length(webpage_urls)-i, "页\n")
  }, error = function(e) {
    cat("第", i, "页抓取失败,URL:", current_url, "错误:", e$message, "\n")
    res_list[[i]] <- NULL
  })
}

# 合并所有结果为表格
final_table <- do.call(rbind, res_list)
注意事项
  • 上述代码默认单页提取的目标值长度固定,如果单页提取结果长度不一致,可以将结果存为列表列,后续再做拆分展开
  • 不要删除停顿相关代码,短时间内发起大量高频请求很容易被站点封禁IP,导致所有请求失效
  • 如果目标页面是动态渲染(内容由JavaScript加载,静态HTML中不存在目标节点),将read_html替换为rvest::read_html_live()即可,整体迭代逻辑不需要改动

内容的提问来源于stack exchange,提问作者flâneur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:06:18