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

如何让R语言爬虫函数直接触发循环next,省略空值判断?

R语言爬虫函数优化:自动触发循环跳过

原函数与当前调用逻辑

你编写的get_page函数用于网页爬虫的错误处理,原代码如下:

get_page <- function(url, user_agent = "my information", skipped) {
  
  headers <- add_headers(`User-Agent` = user_agent)
  
  if (!exists(skipped, envir = .GlobalEnv)) {
    assign(skipped, c(), envir = .GlobalEnv)
  }
  
  for (attempt in 1:4) {
    response <- GET(url, headers = headers)
    http_code <- response$status_code
    
    if (http_code == 200) {
      page <- read_html(rawToChar(response$content))
      return(page)
    } else if (http_code %in% c(400, 401, 403, 404)) {
      cat("HTTP", http_code, "error for", url, "\n")
      assign(skipped, c(get(skipped), url), envir = .GlobalEnv)
      return(NULL)
    }
    
    print(http_code)
    
    if (attempt == 4) {
      cat("Skipped", url, "\n")
      assign(skipped, c(get(skipped), url), envir = .GlobalEnv)
      return(NULL)
    }
    
    Sys.sleep(30)
  }
}

当前调用时,必须手动判断返回值是否为NULL,再执行next跳过当前循环:

for (url in urls){ 
  page <- get_page(url, skipped = "skipped_pers_aau")
  
  if (is.null(page)) {
    next
  }

  #...解析与存储代码
}

需求

希望修改后,调用get_page时无需手动写空值判断,函数能直接触发外层循环跳转到下一个URL,调用逻辑简化为:

for (url in urls){ 
  page <- get_page(url, skipped = "skipped_pers_aau")
  
  #...解析与存储代码
}

可行解决方案

R语言中函数无法直接操控外层循环的next语句,但可以通过以下两种方式实现需求:

方法1:自定义错误+捕获处理

修改get_page,当需要跳过URL时不返回NULL,而是抛出带有自定义类的错误;然后在循环中用tryCatch捕获该错误,自动执行next。

修改后的get_page函数:

get_page <- function(url, user_agent = "my information", skipped) {
  
  headers <- add_headers(`User-Agent` = user_agent)
  
  if (!exists(skipped, envir = .GlobalEnv)) {
    assign(skipped, c(), envir = .GlobalEnv)
  }
  
  for (attempt in 1:4) {
    response <- GET(url, headers = headers)
    http_code <- response$status_code
    
    if (http_code == 200) {
      page <- read_html(rawToChar(response$content))
      return(page)
    } else if (http_code %in% c(400, 401, 403, 404)) {
      msg <- paste("HTTP", http_code, "error for", url)
      cat(msg, "\n")
      assign(skipped, c(get(skipped), url), envir = .GlobalEnv)
      # 抛出自定义类的错误
      stop(structure(list(message = msg, url = url), class = "skip_url_error"))
    }
    
    print(http_code)
    
    if (attempt == 4) {
      msg <- paste("Skipped", url)
      cat(msg, "\n")
      assign(skipped, c(get(skipped), url), envir = .GlobalEnv)
      # 抛出自定义类的错误
      stop(structure(list(message = msg, url = url), class = "skip_url_error"))
    }
    
    Sys.sleep(30)
  }
}

简化后的调用逻辑:

for (url in urls){ 
  page <- tryCatch(
    get_page(url, skipped = "skipped_pers_aau"),
    # 捕获自定义错误,执行next跳过当前循环
    skip_url_error = function(e) {
      next
    }
  )
  
  #...解析与存储代码
}

方法2:封装循环逻辑

把URL循环、空值判断的逻辑封装到一个新函数中,外部只需调用这个封装函数,无需关注内部的跳过逻辑。

封装后的爬虫函数:

crawl_urls <- function(urls, user_agent = "my information", skipped_name = "skipped_pers_aau") {
  # 初始化skipped向量
  if (!exists(skipped_name, envir = .GlobalEnv)) {
    assign(skipped_name, c(), envir = .GlobalEnv)
  }
  
  for (url in urls) {
    page <- get_page(url, user_agent, skipped_name)
    if (is.null(page)) next
    #...这里放置你的解析与存储代码
  }
}

外部调用时只需执行:

crawl_urls(urls)

两种方法各有优劣:方法1保留了外层循环的灵活性,适合需要在循环中添加额外逻辑的场景;方法2调用更简洁,适合标准化的爬虫流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 12:52:44